Skip to content

grust-ladybug: bulk loads can skip the stored-key read-back for fresh rows - #8

Closed
alexy wants to merge 3 commits into
turso-mvcc-concurrencyfrom
ladybug-fresh-load
Closed

alexy wants to merge 3 commits into
turso-mvcc-concurrencyfrom
ladybug-fresh-load

Conversation

@alexy

@alexy alexy commented Sep 18, 2026

Copy link
Copy Markdown
Member

Stacked on #6; one commit.

put_graph on the Ladybug adapter reads back every existing node id and (from, to) pair of a target table before copying, so rows that already exist take the per-row upsert path (kept in #7, skipped only when the table is empty). A caller that feeds one fresh graph as many chunks pays that full scan on every chunk after the first — quadratic in the chunk count. In the strain harness, which loads large graphs in 5 M-edge chunks, soc-Pokec had not finished loading after 65 minutes on the reference host (store file static, one thread iterating rows), and com-Orkut's 24 chunks would have taken days.

LadybugGraphStore::set_bulk_load_trusts_fresh_rows(true) turns the read-back off for a caller that knows its chunks carry no key the store already holds: every row is copied, and a duplicate key in the input is the caller's error (a node COPY fails on it; a relationship table takes it as a parallel edge). Off by default; single-row writes and the non-bulk paths are unaffected. 19/19 crate tests pass (eigen).

The harness sets it (AG_LADYBUG_BULK=readback restores the read-back), tags such rows ladybug_bulk=fresh so earlier rows are not superseded silently, and pins this head for the Ladybug ladder.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sak2FQcdgs5pkL2ruKrSUZ

alexy and others added 3 commits September 18, 2026 11:12
…caller vouches its rows are fresh

put_graph reads back every existing node id and (from, to) pair of a target
table before copying, so rows that already exist take the upsert path. A
caller that feeds one fresh graph as many chunks pays that full scan on every
chunk after the first, quadratic in the chunk count: soc-Pokec in 5 M-edge
chunks had not finished loading after 65 minutes on the reference host, and
com-Orkut's 24 chunks would take days. set_bulk_load_trusts_fresh_rows(true)
turns the read-back off for a caller that knows its chunks carry no stored
key; every row is copied, and a duplicate key in the input is the caller's
error. Off by default; single-row writes are unaffected.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sak2FQcdgs5pkL2ruKrSUZ
…rried endpoints

A chunked load carries each edge batch's endpoint nodes again, so with the
read-back off the node COPY failed on a duplicate primary key on the second
chunk. The store now remembers, per table, the node ids it copied in this
mode and skips them; relationship rows are still all copied. Test: nodes
first, then four edge chunks each carrying their endpoints.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sak2FQcdgs5pkL2ruKrSUZ
…l edges

The fresh-rows path still keyed the copy batch by (from, to), so a multigraph
chunk collapsed its parallel edges to one per pair while put_graph reported
every row written: on sx-stackoverflow the strain harness then found the hub's
degree at 41,348 against the oracle's 104,863. With the read-back off there
is nothing to merge against, so every row is copied in input order; the
read-back path keeps its one-row-per-pair upsert. Test: two parallel edges
with distinct ids land and read back as two.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sak2FQcdgs5pkL2ruKrSUZ
alexy added a commit that referenced this pull request Sep 18, 2026
Brings in PR #6 (durable group commit, parallel MVCC loads, FK-off loads and
the WAL/MVCC comparison) and PR #8 (Ladybug bulk COPY loads and fresh-row
mode) ahead of the Tadpole release.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@alexy

alexy commented Sep 19, 2026

Copy link
Copy Markdown
Member Author

Closing: all three commits (dd4c50f, 8b84c0e, 7152d6a) are in main as of 2bf244e (7152d6a is an ancestor of main), so this PR is merged through main rather than through its stacked base. The strain harness pins 7152d6a.

@alexy alexy closed this Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant