Repository navigation
feat: expose cypherengine as a rust api and rename crates to lance-csr - #53
Merged
Merged
Conversation
Upstream owns the lance-graph and lance-graph-catalog names on crates.io, so publishing needs our own. Renames the crates, directories and Rust paths to lance-csr*, points the manifests at this repository, and ships LICENSE and NOTICE with the published crates.
Deploying lance-csr with
|
| Latest commit: |
9f28927
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d268ab7f.lance-csr.pages.dev |
| Branch Preview URL: | https://chore-rename-crates-lance-cs.lance-csr.pages.dev |
Move the cached engine (snapshot, CSR adjacencies, node indexes, join-key statistics and refresh) from the PyO3 bindings into the lance-csr crate as an async CypherEngine. The Python class is now a thin wrapper with the same API and exception types. refresh() now holds an async lock for the whole operation, so overlapping refreshes can no longer publish an older snapshot after a newer one (fixes #12). Add engine tests, a deterministic refresh race test, a runnable embedded_query example that CI runs, and a "Using from Rust" docs page whose snippets are included from that example. Bump the crates and the Python package to 0.3.0.
prrao87
marked this pull request as ready for review
October 26, 2026 15:51
prrao87
added a commit
that referenced
this pull request
Oct 26, 2026
* perf(graph): search shortest paths from both ends Resolve #17 with complete-layer bidirectional search for single-target CSR queries, preserving all shortest paths and duplicate edges. Keep shared forward search for multiple targets. Developed by David Hughes with assistance from Codex. * docs: add readme branding and contribution templates (#29) * feat: expose cypherengine as a rust api and rename crates to lance-csr (#53) * chore: rename rust crates to lance-csr for crates.io Upstream owns the lance-graph and lance-graph-catalog names on crates.io, so publishing needs our own. Renames the crates, directories and Rust paths to lance-csr*, points the manifests at this repository, and ships LICENSE and NOTICE with the published crates. * feat: expose CypherEngine as a Rust API and bump to 0.3.0 Move the cached engine (snapshot, CSR adjacencies, node indexes, join-key statistics and refresh) from the PyO3 bindings into the lance-csr crate as an async CypherEngine. The Python class is now a thin wrapper with the same API and exception types. refresh() now holds an async lock for the whole operation, so overlapping refreshes can no longer publish an older snapshot after a newer one (fixes #12). Add engine tests, a deterministic refresh race test, a runnable embedded_query example that CI runs, and a "Using from Rust" docs page whose snippets are included from that example. Bump the crates and the Python package to 0.3.0. --------- Co-authored-by: Prashanth Rao <35005448+prrao87@users.noreply.github.com> Co-authored-by: prrao87 <prrao87@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
lance-csr's engine could only be used through Python. The Rust crate had the parser and planner, but the part that makes lance-csr fast (the cached snapshot, CSR adjacencies, node indexes, join-key statistics and
refresh()) lived inside the PyO3 bindings, tied to the GIL and Python exceptions. A Rust program, such as a desktop app backend, had to rebuild all of that by hand.This PR makes
CypherEnginea Rust library API and prepares the crates for crates.io and the 0.3.0 release. Upstream LanceDB ownslance-graphandlance-graph-catalogon crates.io, so the crates are also renamed tolance-csr*.What changed
Rust engine.
lance_csr::CypherEngineis now a public async API with the same behaviour as the Python class:EngineSource::open_lance(uri, version, storage_options)orEngineSource::Arrow(batch).execute,execute_stream,explain,execute_with_vector_rerank,refresh,csr_stats,node_index_statsanddataset_versionsreturn Rust types andGraphError.block_oncalls replaced by.await; the snapshot, CSR delta and statistics logic is unchanged.Python bindings.
CypherEnginein Python is now a thin wrapper: it converts Python inputs, calls the Rust engine and converts results. Its API, behaviour and exception types are unchanged. Errors map to the sameValueError,NotImplementedErrorandRuntimeErroras before.Concurrent
refresh()fix. This fixes issue #12, "Prevent concurrent refreshes from publishing stale snapshots": overlapping refreshes could publish an older snapshot after a newer one.refresh()now holds an async lock for the whole operation, so concurrent calls run one at a time and each publishes the latest data. Queries never wait for it. A deterministic regression test covers it (see Validation).Fixes #12
Crate rename.
lance-graph→lance-csr,lance-graph-catalog→lance-csr-catalog, plus the unpublished benches and Python binding crates. Manifests point at this repository, and the published crates shipLICENSEandNOTICE. The Python package name and import path don't change.Docs and examples.
examples/embedded_query.rs(enabled throughpymdownx.snippets), which CI now runs.Version. 0.2.0 → 0.3.0 across the crates and the Python package.
CSR expansion memory (#11) is not addressed here; it needs a change to the expansion operator itself.
Validation
cargo fmt --check,cargo clippy --workspace --all-targets -- -D warnings(and in the Python crate) pass.cargo test --workspacepasses, including new engine tests:refresh()cargo run -p lance-csr --example embedded_queryprints the documented output.python/:make install,make test(332 passed) andmake lintpass on the 0.3.0 build, anddocs/check_snippets.pypasses.zensical build --strictandtypospass.cargo publish --workspace --dry-runpackages and verifies both crates at 0.3.0; nothing has been published.cargo docreports three broken intra-doc links that predate this PR; nothing new.Benchmarks
I compared the published 0.2.0 wheel from PyPI with a release wheel of this branch on both suites, using the published settings (Apple M5, macOS, 5+ rounds). Baseline and branch runs alternated. The table gives the geometric mean of the per-query median ratio (branch / 0.2.0, below 1 is faster):
All 88 result assertions passed on both sides. The lazy runs leaned slower when the baseline ran first and evened out when the order was reversed, so I read them as noise.
engine_cache.py(20 tables) is flat: construction 78.0 → 76.8 ms, warm query 1.87 → 1.87 ms, unchanged refresh 1.14 → 1.15 ms. Published benchmark tables are unchanged.Not run: the release wheel workflow on Linux.
🤖 Generated with Claude Code