Skip to content

fix: isolate Foyer cache origins and avoid warm size writes - #3

Merged
zhangstar333 merged 1 commit into
zhangstar333:lance_foyerfrom
Gabriel39:fix/foyer-cache-origin-isolation
Sep 30, 2026
Merged

zhangstar333 merged 1 commit into
zhangstar333:lance_foyerfrom
Gabriel39:fix/foyer-cache-origin-isolation

Conversation

@Gabriel39

@Gabriel39 Gabriel39 commented Sep 30, 2026 •

Copy link
Copy Markdown

Reading the same bucket/path through distinct object-store endpoints could return another origin's cached metadata, size, or bytes. Give each live underlying store a random namespace shared across dataset scopes and cache owners, and bump the cache-key version. The registry holds weak references and removes expired identities, so neither address reuse nor recovered disk entries can join unrelated stores.

The wrapper API does not expose a complete stable backend identity. A new store instance or process restart therefore starts cold; reuse remains available for the same live store. Document this tradeoff and exercise a fresh Dataset open followed by a warm rescan in the C API regression.

Avoid reinserting unchanged size records into the WriteOnInsertion hybrid cache. Check both tiers so warm reads, including recovered entries with a cold metadata cache, do not enqueue disk writes.

This is one supplementary commit on the current lance_foyer base, retaining its Foyer 0.22.6 dependency. It supplements lance-format#73.

Validation on this base:

  • cargo test --locked: 461 regular Rust tests passed, including distinct HTTP endpoint isolation, batched reads and NotFound isolation, recovered-cache origin replacement, weak-reference lifetime, warm disk-write bytes, and repeated C API scans.
  • cargo clippy --locked --all-targets -- -D warnings: passed.
  • cargo fmt -- --check and git diff --cached --check: passed.
  • The three opt-in native consumer tests were not rerun for this refresh.

@Gabriel39
Gabriel39 force-pushed the fix/foyer-cache-origin-isolation branch from 24c7ca4 to c543c78 Compare September 30, 2026 08:18
@zhangstar333
zhangstar333 merged commit df0b202 into zhangstar333:lance_foyer Sep 30, 2026
Gabriel39 added a commit to apache/doris that referenced this pull request Sep 30, 2026
…68613)

Unfiltered ANN searches scoped to complete index segments can spend time
materializing redundant row-ID allowlists. Update lance-c to an
immutable upstream revision containing the merged Lance
development-branch fix lance-format/lance#9599 and ANN diagnostics from
lance-format/lance#9602, through lance-format/lance-c#89.

Keep all master changes in `thirdparty/`. Remove the superseded local
lance-c patch chain and retain the Foyer cache integration while its
interface remains outside upstream main. The upstream revision also
carries the merged lance-format/lance#9537 PQ scoring change and ANN
stage timing diagnostics; no Doris FE or BE code changes are included
here.

The prefilter fast path requires complete visible coverage of every
selected segment and no predicate. Partial coverage and predicates
retain row-ID prefiltering, while deletions and unindexed fallback
remain effective.

Pin lance-c `9bd730add2ac70316c1d642b8459011e2dd92022`, using the merged
Lance #9602 revision `68c12dfd7efe02f90ad2d7f3a239a7eb64884e57`. This
includes parallel-path partition-preparation timing. The upstream
callback regression checks timer presence and nanosecond units while
accepting valid zero durations.

The Foyer wrapper caches immutable ObjectMeta and Attributes
independently of HTTP response extensions, avoiding repeated HEAD
requests on warm range reads. It does not replay transport extensions
from cached metadata. The HTTP regression checks HEAD/GET counts,
returned bytes/ranges/metadata, fresh dataset scopes, and explicit HEAD
bypass.

Generate the retained Foyer patch from source commit
`24c7ca4bcb9422c113b0d3e07e4efe1173b0bc9f` relative to the pinned
lance-c baseline. The header records both revisions and the regeneration
command. The source is submitted as
zhangstar333/lance-c#3 against the branch behind
lance-format/lance-c#73, on top of merged source-alignment PR #2. Doris
consumes the exact reviewed source revision while that supplementary PR
awaits merge.

Scope metadata, size, and block keys to a random namespace for each live
underlying object-store instance. The wrapping API omits a complete
stable backend identity; identical bucket/path names alone cannot
distinguish S3-compatible endpoints. Weak identity records preserve
sharing for the same live store without retaining it, while new stores
and process restarts start cold. A fresh Dataset open that creates a new
store consequently needs to warm its own cache. This deliberately
reduces reuse across instances to prevent returning another origin's
data; it does not claim unchanged cache-hit rates or production latency.

Avoid inserting an unchanged size entry into the WriteOnInsertion hybrid
cache: look up both tiers first and populate only absent or invalid size
records. Regression tests cover real HTTP endpoints sharing
bucket/path/ETag, batched data and NotFound isolation, replaced origins
after disk recovery, weak-reference lifetime, and actual disk-write
bytes. Five warm range reads wrote 40 KB before the fix and zero bytes
after it in the regression.

Fingerprint the patch in the downloader so existing source trees refresh
after updates, including legacy empty markers. Identical patches reuse
cached sources. Check platform definitions under nounset with simulated
Darwin x86_64/arm64, and make the optional ADBC source guard safe when
unset on master. Downloader lifecycle and platform handling remain
downstream in Doris.

Validation: 461 regular Rust tests passed on the final source; Rust
formatting and diff checks passed. GNU patch and git apply checks
passed, and all 87 tracked source files match the recorded source
commit. Downloader tests passed on master, branch-4.1, and the
downstream hotfix branch for fresh extraction, idempotence,
re-extraction, generic markers, legacy/mismatched Foyer markers, and
patch failure. Shell syntax and simulated macOS initialization passed.
All three opt-in native consumer tests passed: C calls, C++ calls, and
static OSS HTTP transport. Full Doris builds and BE integration
execution remain in PR CI.
Gabriel39 added a commit to apache/doris that referenced this pull request Sep 30, 2026
…nch-4.1) (#68615)

Unfiltered ANN searches scoped to complete index segments can
materialize redundant row-ID allowlists, and the existing scan profile
leaves the remaining search work unexplained. Update the upstream
dependency and expose ANN stage timings on `branch-4.1`.

This includes the dependency integration from #68613: adopt the merged
lance-format/lance#9599 and lance-format/lance#9602 through
lance-format/lance-c#89, retain the merged lance-format/lance#9537 PQ
scoring fix, remove superseded local lance-c patches, and retain only
the Foyer cache integration.

Add BE profile counters for index opening, partition
loading/preparation, prefilter readiness, CPU queue wait, partition
search, query lookup-table preparation, fused distance/TopK work, and
result materialization. Export operator baselines for ANN, sort/merge,
take, and vector-distance work. Extend the existing indexed multivector
regression to check that stage timers reach the Doris profile, alongside
existing result and prefilter assertions.

Timings accumulate across concurrent work and overlap parent stages.
Distance/TopK includes candidate filtering in fused paths; these
counters must not be summed to reconstruct wall time.
`docs/lance-ann-profile.md` documents the boundaries, supported paths,
and relationship to the existing scanner and prefilter timers. The BE
changes add observability; the prefilter optimization itself remains in
the upstream dependency.

Pin lance-c `9bd730add2ac70316c1d642b8459011e2dd92022`, using the merged
Lance #9602 revision `68c12dfd7efe02f90ad2d7f3a239a7eb64884e57`. This
includes parallel-path partition-preparation timing. The upstream
callback regression checks timer presence and nanosecond units while
accepting valid zero durations.

The Foyer wrapper caches immutable ObjectMeta and Attributes
independently of HTTP response extensions, avoiding repeated HEAD
requests on warm range reads. It does not replay transport extensions
from cached metadata. The HTTP regression checks HEAD/GET counts,
returned bytes/ranges/metadata, fresh dataset scopes, and explicit HEAD
bypass.

Generate the retained Foyer patch from source commit
`24c7ca4bcb9422c113b0d3e07e4efe1173b0bc9f` relative to the pinned
lance-c baseline. The header records both revisions and the regeneration
command. The source is submitted as
zhangstar333/lance-c#3 against the branch behind
lance-format/lance-c#73, on top of merged source-alignment PR #2. Doris
consumes the exact reviewed source revision while that supplementary PR
awaits merge.

Scope metadata, size, and block keys to a random namespace for each live
underlying object-store instance. The wrapping API omits a complete
stable backend identity; identical bucket/path names alone cannot
distinguish S3-compatible endpoints. Weak identity records preserve
sharing for the same live store without retaining it, while new stores
and process restarts start cold. A fresh Dataset open that creates a new
store consequently needs to warm its own cache. This deliberately
reduces reuse across instances to prevent returning another origin's
data; it does not claim unchanged cache-hit rates or production latency.

Avoid inserting an unchanged size entry into the WriteOnInsertion hybrid
cache: look up both tiers first and populate only absent or invalid size
records. Regression tests cover real HTTP endpoints sharing
bucket/path/ETag, batched data and NotFound isolation, replaced origins
after disk recovery, weak-reference lifetime, and actual disk-write
bytes. Five warm range reads wrote 40 KB before the fix and zero bytes
after it in the regression.

Fingerprint the patch in the downloader so existing source trees refresh
after updates, including legacy empty markers. Identical patches reuse
cached sources. Check platform definitions under nounset with simulated
Darwin x86_64/arm64, and make the optional ADBC source guard safe when
unset on master. Downloader lifecycle and platform handling remain
downstream in Doris.

Validation: 461 regular Rust tests passed on the final source; Rust
formatting and diff checks passed. GNU patch and git apply checks
passed, and all 87 tracked source files match the recorded source
commit. Downloader tests passed on master, branch-4.1, and the
downstream hotfix branch for fresh extraction, idempotence,
re-extraction, generic markers, legacy/mismatched Foyer markers, and
patch failure. Shell syntax and simulated macOS initialization passed.
All three opt-in native consumer tests passed: C calls, C++ calls, and
static OSS HTTP transport. Full Doris builds and BE integration
execution remain in PR CI.
yiguolei pushed a commit to apache/doris that referenced this pull request Oct 8, 2026
…nch-4.1) (#68615)

Unfiltered ANN searches scoped to complete index segments can
materialize redundant row-ID allowlists, and the existing scan profile
leaves the remaining search work unexplained. Update the upstream
dependency and expose ANN stage timings on `branch-4.1`.

This includes the dependency integration from #68613: adopt the merged
lance-format/lance#9599 and lance-format/lance#9602 through
lance-format/lance-c#89, retain the merged lance-format/lance#9537 PQ
scoring fix, remove superseded local lance-c patches, and retain only
the Foyer cache integration.

Add BE profile counters for index opening, partition
loading/preparation, prefilter readiness, CPU queue wait, partition
search, query lookup-table preparation, fused distance/TopK work, and
result materialization. Export operator baselines for ANN, sort/merge,
take, and vector-distance work. Extend the existing indexed multivector
regression to check that stage timers reach the Doris profile, alongside
existing result and prefilter assertions.

Timings accumulate across concurrent work and overlap parent stages.
Distance/TopK includes candidate filtering in fused paths; these
counters must not be summed to reconstruct wall time.
`docs/lance-ann-profile.md` documents the boundaries, supported paths,
and relationship to the existing scanner and prefilter timers. The BE
changes add observability; the prefilter optimization itself remains in
the upstream dependency.

Pin lance-c `9bd730add2ac70316c1d642b8459011e2dd92022`, using the merged
Lance #9602 revision `68c12dfd7efe02f90ad2d7f3a239a7eb64884e57`. This
includes parallel-path partition-preparation timing. The upstream
callback regression checks timer presence and nanosecond units while
accepting valid zero durations.

The Foyer wrapper caches immutable ObjectMeta and Attributes
independently of HTTP response extensions, avoiding repeated HEAD
requests on warm range reads. It does not replay transport extensions
from cached metadata. The HTTP regression checks HEAD/GET counts,
returned bytes/ranges/metadata, fresh dataset scopes, and explicit HEAD
bypass.

Generate the retained Foyer patch from source commit
`24c7ca4bcb9422c113b0d3e07e4efe1173b0bc9f` relative to the pinned
lance-c baseline. The header records both revisions and the regeneration
command. The source is submitted as
zhangstar333/lance-c#3 against the branch behind
lance-format/lance-c#73, on top of merged source-alignment PR #2. Doris
consumes the exact reviewed source revision while that supplementary PR
awaits merge.

Scope metadata, size, and block keys to a random namespace for each live
underlying object-store instance. The wrapping API omits a complete
stable backend identity; identical bucket/path names alone cannot
distinguish S3-compatible endpoints. Weak identity records preserve
sharing for the same live store without retaining it, while new stores
and process restarts start cold. A fresh Dataset open that creates a new
store consequently needs to warm its own cache. This deliberately
reduces reuse across instances to prevent returning another origin's
data; it does not claim unchanged cache-hit rates or production latency.

Avoid inserting an unchanged size entry into the WriteOnInsertion hybrid
cache: look up both tiers first and populate only absent or invalid size
records. Regression tests cover real HTTP endpoints sharing
bucket/path/ETag, batched data and NotFound isolation, replaced origins
after disk recovery, weak-reference lifetime, and actual disk-write
bytes. Five warm range reads wrote 40 KB before the fix and zero bytes
after it in the regression.

Fingerprint the patch in the downloader so existing source trees refresh
after updates, including legacy empty markers. Identical patches reuse
cached sources. Check platform definitions under nounset with simulated
Darwin x86_64/arm64, and make the optional ADBC source guard safe when
unset on master. Downloader lifecycle and platform handling remain
downstream in Doris.

Validation: 461 regular Rust tests passed on the final source; Rust
formatting and diff checks passed. GNU patch and git apply checks
passed, and all 87 tracked source files match the recorded source
commit. Downloader tests passed on master, branch-4.1, and the
downstream hotfix branch for fresh extraction, idempotence,
re-extraction, generic markers, legacy/mismatched Foyer markers, and
patch failure. Shell syntax and simulated macOS initialization passed.
All three opt-in native consumer tests passed: C calls, C++ calls, and
static OSS HTTP transport. Full Doris builds and BE integration
execution remain in PR CI.
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.

2 participants