Add thread query performance specification

Bound /posts/:txid/thread to per-thread reads: prefix-scan postChildren
by parent txid and scope like counts to the thread's txids instead of
the global postLikes scan. Record both implementation parts in the
feature backlog.

By specifier.
This commit is contained in:
Chris Troutner
2026-09-15 12:10:01 -07:00
parent 8244e11ec4
commit 9db1137686
2 changed files with 52 additions and 5 deletions
@@ -0,0 +1,27 @@
# Scenarios: Thread query performance - 1
#
# GET /posts/:txid/thread currently does work proportional to the whole
# database, not to the requested thread:
# - get-post-thread.js calls buildLikeCountMap(), which iterates every
# postLikes entry and loads one post per like just to compute counts.
# - get-post-thread.js loadChildTxids() iterates every postChildren entry
# for each node in the thread instead of prefix-scanning that node's
# parent key.
# This feature pins the endpoint to bounded, per-thread reads. Thread shape,
# reply ordering, and per-node likeCount remain specified by like-counts.feature.
Feature: Thread query performance
Background:
Given a psf-memo-db instance with posts, postHeights, addrPostHeights, postChildren, likes, and postLikes stores
Given the fixture "posts-with-likes" is loaded into the posts and likes stores
Scenario Outline: Thread query performance - 1 GET /posts/:txid/thread performs work bounded by the thread
When the client requests the thread for <txid>
Then the post with txid <txid> has likeCount <likeCount>
And the postChildren store was read at most <max_entries> entries
And no more than <limit> posts are loaded by txid
Examples:
| txid | likeCount | max_entries | limit |
| post-200-a | 2 | 1 | 2 |
| post-200-b | 1 | 0 | 1 |
+25 -5
View File
@@ -157,16 +157,36 @@ Reference: https://memo.sv/protocol (Wayback snapshot 2025-12-15)
--- ---
## Next up: account avatar display — DONE (2026-09-05) ## Next up: Thread query performance (psf-memo-db)
`GET /posts/:txid/thread` is slow because `get-post-thread.js` does work
proportional to the whole database instead of the requested thread. Two
independent parts, one feature spec:
- **Part A — like counts scoped to the thread.** `execute()` calls
`buildLikeCountMap()`, which iterates every `postLikes` entry and loads one
post per like. Build the thread first, then count likes for the thread's
txids via the existing `countLikesForTxids`.
- **Part B — child loading uses the parent index.** `loadChildTxids()`
iterates every `postChildren` entry once per thread node. Prefix-scan
`parentTxid:childTxid` (as `countRepliesForTxids` already does) instead.
Spec: `psf-memo-db/specs/thread-query-performance.feature`. Affected
component: D (`psf-memo-db`). No client, indexer, or protocol changes.
Thread shape, reply ordering, and per-node `likeCount` remain specified by
`psf-memo-db/specs/like-counts.feature` (scenario 3). `buildLikeCountMap`
still has unit/property coverage; the coder should update it if the method is
removed.
---
## Previous: account avatar display — DONE (2026-09-05)
The `/account` page now renders the avatar image when an avatar URL is set The `/account` page now renders the avatar image when an avatar URL is set
(pure `AvatarImage` component + `AccountPage` display helpers). Merged to (pure `AvatarImage` component + `AccountPage` display helpers). Merged to
`master` at `5afaa64`. `master` at `5afaa64`.
Next feature: TBD — current direction is front-end improvements to
`psf-memo-client` (UI/UX polish, accessibility, performance, responsiveness,
state handling, error surfacing).
## Notes for future cycles ## Notes for future cycles
- Broadcast result (txid) is returned immediately; the action appears in the - Broadcast result (txid) is returned immediately; the action appears in the