Skip to content

feat(csr): report how far the base csr trails the data - #93

Merged
prrao87 merged 1 commit into
mainfrom
feat/csr-freshness-stats
Oct 30, 2026
Merged

prrao87 merged 1 commit into
mainfrom
feat/csr-freshness-stats

Conversation

@prrao87

@prrao87 prrao87 commented Oct 30, 2026

Copy link
Copy Markdown
Member

Why

csr_stats() says how a refresh updated the CSR, but not how far its base trails the data. delta_edges counts every edge appended since the last full build, including ones deleted since, so it can't tell you how many live edges sit outside the base. This is the reporting half of #75, using the terms Lance's index statistics use. The explicit optimize step it also asks for is left for a later PR, so #75 stays open.

What changed

csr_stats() reports two new fields per relationship type, in Rust (CsrStats) and Python:

  • base_version: the relationship dataset version of the last full build (None for PyArrow input). It trails version while refreshes apply deltas.
  • unindexed_edges: live edges outside the base CSR, appended since its last full build and not since removed. Lance calls this num_unindexed_rows.
lance.write_dataset(edges([(1, 2), (39, 0), (5, 5)]), uri, mode="append")
engine.refresh()
engine.csr_stats()["KNOWS"]
# {'edges': 203, 'delta_edges': 3, 'tombstones': 0, 'unindexed_edges': 3,
#  'update': 'delta', 'version': 2, 'base_version': 1, 'build_ms': ...}

To make unindexed_edges exact, the adjacency now counts tombstones that remove appended edges separately from those that remove base edges. Query results don't change: base plus delta already gives exact answers for the pinned snapshot. The new fields only say how much of the work the delta carries.

The CSR guide's field table and the "How to keep the CSR fresh" steps describe both fields.

Validation

  • Rust: 671 tests pass, plus clippy with -D warnings and cargo fmt --check. Unit tests cover tombstones on base and appended edges, including an appended edge from a source key the base doesn't have.
  • Python: 1,646 tests pass, plus ruff and pyright. The delta tests check both fields after the first build, an append, mixed appends and deletes (one delete removes an appended edge), and a rebuild.
  • Docs: strict Zensical build and typos pass.
  • No benchmark run for this change on its own: it adds a counter on refresh and nothing on the query path. Read target columns once when a CSR hop fetches a large share of a node table #86, stacked on this branch, was benchmarked with it.

🤖 Generated with Claude Code

csr_stats() now reports base_version, the relationship dataset version of
the last full build, and unindexed_edges, the live edges held outside the
base (appended since that build and not since removed). delta_edges counts
every append, including ones later deleted, so it can't answer that.

Tombstones that remove appended edges are counted separately in Adjacency
to make the live count exact.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying lance-csr with  Cloudflare Pages  Cloudflare Pages

Latest commit: e4cdf72
Status: ✅  Deploy successful!
Preview URL: https://7eb5168a.lance-csr.pages.dev
Branch Preview URL: https://feat-csr-freshness-stats.lance-csr.pages.dev

View logs

@prrao87
prrao87 marked this pull request as ready for review October 30, 2026 19:38
@prrao87
prrao87 merged commit a75ef16 into main Oct 30, 2026
8 checks passed
@prrao87
prrao87 deleted the feat/csr-freshness-stats branch October 30, 2026 19:38
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