Skip to content

keyvaluestorage: sort IterateValues by id so Iterate groups whole keys (SYN-116) - #753

Merged
cheggaaa merged 1 commit into
v0.13.xfrom
cheggaaa/syn-116-iteratevalues-sort
Jul 30, 2026
Merged

keyvaluestorage: sort IterateValues by id so Iterate groups whole keys (SYN-116)#753
cheggaaa merged 1 commit into
v0.13.xfrom
cheggaaa/syn-116-iteratevalues-sort

Conversation

@cheggaaa

Copy link
Copy Markdown
Member

Storage.Iterate builds its per-key callback groups from consecutive rows, but innerstorage.IterateValues scanned with no sort — SQLite full-scans in rowid (insertion) order, so one key's rows split across multiple callbacks whenever peers' row batches interleave, and the split is stable across restarts (upsert preserves rowids). Any consumer treating a callback as "all rows of this key" silently misbehaves; in the SDK this froze read-marker republish (SYN-97 — same 16 keys re-broadcast on every boot, forever).

Fix: IterateValues sorts by id (key+"-"+peerId), the same ordering IteratePrefix already uses, so the consecutive-run grouping actually groups by key. The diff-loading scans in New/init stay unsorted — ldiff.Set is order-independent.

Regression test inserts per-peer batches (16 keys × 3 peers, one key's rows maximally non-adjacent in insertion order) and asserts the scan is id-ordered and every key's rows form one consecutive run; it fails on the previous unsorted scan.

Measured cost of the sorted scan (any-store v0.4.7): 10k rows 2.0ms → 3.2ms, 50k rows 9.9ms → 18.5ms per full iteration.

Tracked as SYN-116.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WCH11UrasWuzpKpgHRepow

Storage.Iterate builds per-key callback groups from consecutive runs,
but IterateValues scanned unsorted (insertion order), so one key's rows
split across groups whenever peers' row batches interleaved — and the
split is stable across restarts. Consumers treating a callback as "all
rows of this key" silently misbehaved (SYN-116; froze read-marker
republish in the SDK, SYN-97).

Sorting by id (key+"-"+peerId) makes the grouping group by key, same
as IteratePrefix. The diff-loading scans stay unsorted — ldiff.Set is
order-independent.

Claude-Session: https://claude.ai/code/session_01WCH11UrasWuzpKpgHRepow
@cheggaaa
cheggaaa merged commit 74adbfb into v0.13.x Jul 30, 2026
3 checks passed
@cheggaaa
cheggaaa deleted the cheggaaa/syn-116-iteratevalues-sort branch July 30, 2026 13:39
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant