fix(index): compare store logical identity for scalar cache reuse - #9086
Closed
LuQQiu wants to merge 1 commit into
Closed
fix(index): compare store logical identity for scalar cache reuse#9086LuQQiu wants to merge 1 commit into
LuQQiu wants to merge 1 commit into
Conversation
`LanceIndexStore::is_same_storage_binding` gated cache reuse on `Arc::ptr_eq(object_store)`, so it only returned true when both stores were the exact same Arc instance. When a fresh `ObjectStore` is constructed per index access (which happens whenever the index is reached through an indirection rather than a shared handle), the pointers differ, so every access is treated as a store rotation: the cached scalar index is dropped and reloaded, and any per-query preparation built on top of it (e.g. an FTS scorer) is rebuilt from scratch on every query. Compare the store's logical identity instead: `store_prefix` uniquely identifies the underlying store (scheme, bucket/account, and any wrapping), so two stores reopened for the same location share it even as distinct Arc instances, while different locations still differ. Adds a regression test asserting that two stores opened separately for the same location share a binding (and different locations do not).
Contributor
Author
|
Superseded by #9075. My change restored performance by loosening is_same_storage_binding to compare store_prefix, but that would let one request reuse another request's live index and cross the credential/wrapper isolation boundary required by #7959. #9075 is the correct fix: it keeps storage handles request-bound while sharing the reader-free FTS state (stats/scorer/metadata) across requests, and avoids reopening partition files on rebind. Verified #9075 restores single-token QPS to ~3884 (baseline ~3965) with scorer_build_ms back to 0. |
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.
Problem
LanceIndexStore::is_same_storage_bindingdecides whether a cached scalar index can be reused for a given store. It compared the store by Arc pointer identity:This only returns
truewhen both stores are the exact sameArcinstance. When a freshObjectStoreis constructed per index access — which happens whenever the index is reached through an indirection rather than a single shared handle — the twoArcs differ even though they point at the same underlying storage.index_for_store(registry.rs) then returnsNone, so every access is treated as a store rotation: the cached scalar index is dropped and reloaded, and any per-query state built on top of it (e.g. a prepared FTS scorer) is rebuilt from scratch on every query.The effect is severe for FTS: a warm single-token query that should take a few ms instead spends seconds rebuilding the scorer, because the resident/prewarmed cache is never actually hit.
Fix
Compare the store's logical identity instead of the Arc pointer:
store_prefixis documented as uniquely identifying the underlying object store (it encodes the scheme, bucket/account, and any wrapping — information not always present in the URL). Two stores reopened for the same location share it even as distinctArcinstances, so the cache is reused; different locations still differ, so the rotation behavior is preserved.Test
Adds
test_same_storage_binding_ignores_arc_identity: opens twoObjectStores separately for the same path (asserting they are distinctArcs), and assertsis_same_storage_bindingreturnstrue; a different location returnsfalse. Verified the test fails against the oldArc::ptr_eqimplementation and passes with the fix. Fulllance_formatsuite (16 tests) green; fmt/clippy clean.