Skip to content

enhance: add expression filter cache for two-stage search#48883

Open
sparknack wants to merge 3 commits intomilvus-io:masterfrom
sparknack:two-stage-search-cache
Open

enhance: add expression filter cache for two-stage search#48883
sparknack wants to merge 3 commits intomilvus-io:masterfrom
sparknack:two-stage-search-cache

Conversation

@sparknack
Copy link
Copy Markdown
Contributor

Summary

  • Add per-segment LRU cache (ExprFilterCache) to avoid re-executing filter expressions in Stage 2 of two-stage search
  • Stage 1 writes the filter bitset into cache via Put (clone), Stage 2 reads it via one-shot Take (move out + delete entry)
  • Cache is only activated when enable_expr_cache=true, which is exclusively set by two-stage search — normal search/query paths are unaffected

Key design

  • Cache lives on ChunkedSegmentSealedImpl (sealed segments only)
  • Key: filter plan ToString() (exact match, no hash collision risk)
  • Value: (TargetBitmap, valid_bitset) pre-MVCC (MvccNode re-applies)
  • LRU with configurable capacity (autoIndex.twoStageSearch.exprCacheSize, default 16)
  • Move + one-shot Take semantics: zero-copy on read, auto-cleanup
  • No TTL needed: Take deletes entry, stale entries evicted by LRU

issue: #47219

Test plan

  • Unit test test_expr_filter_cache.cpp covering Put/Take/LRU eviction
  • Integration test with two-stage search enabled + filter expressions
  • Verify normal search/query paths are unaffected (cache not activated)

🤖 Generated with Claude Code

Add per-segment LRU cache (ExprFilterCache) to avoid re-executing
filter expressions in Stage 2 of two-stage search. Stage 1 writes
the filter bitset into cache via Put (clone), Stage 2 reads it via
one-shot Take (move out + delete entry). Cache is only activated
when enable_expr_cache=true, which is exclusively set by two-stage
search — normal search/query paths are unaffected.

Key design:
- Cache lives on ChunkedSegmentSealedImpl (sealed segments only)
- Key: filter plan ToString() (exact match, no hash collision risk)
- Value: (TargetBitmap, valid_bitset) pre-MVCC (MvccNode re-applies)
- LRU with configurable capacity (autoIndex.twoStageSearch.exprCacheSize, default 16)
- Move + one-shot Take semantics: zero-copy on read, auto-cleanup
- No TTL needed: Take deletes entry, stale entries evicted by LRU

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
@sre-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sparknack
To complete the pull request process, please assign xiaofan-luan after the PR has been reviewed.
You can assign the PR to them by writing /assign @xiaofan-luan in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sre-ci-robot sre-ci-robot added size/L Denotes a PR that changes 100-499 lines. area/compilation area/internal-api labels Apr 9, 2026
@mergify mergify Bot added dco-passed DCO check passed. kind/enhancement Issues or changes related to enhancement labels Apr 9, 2026
@sre-ci-robot
Copy link
Copy Markdown
Contributor

[ci-v2-notice]
Notice: New ci-v2 system is enabled for this PR.

To rerun ci-v2 checks, comment with:

  • /ci-rerun-code-check // for ci-v2/code-check
  • /ci-rerun-build // for ci-v2/build
  • /ci-rerun-build-all // for ci-v2/build-all (multi-arch builds)
  • /ci-rerun-buildenv // for ci-v2/build-env (build milvus-env builder images)
  • /ci-rerun-ut-integration // for ci-v2/ut-integration, will rerun ci-v2/build
  • /ci-rerun-ut-go // for ci-v2/ut-go, will rerun ci-v2/build
  • /ci-rerun-ut-cpp // for ci-v2/ut-cpp
  • /ci-rerun-ut // for all ci-v2/ut-integration, ci-v2/ut-go, ci-v2/ut-cpp, will rerun ci-v2/build
  • /ci-rerun-e2e-default // for ci-v2/e2e-default
  • /ci-rerun-e2e-amd // for ci-v2/e2e-amd (e2e pool dispatcher)
  • /ci-rerun-build-ut-cov // for ci-v2/build-ut-cov (build + unit tests in one pipeline)
  • /ci-rerun-gosdk // for ci-v2/go-sdk (Go SDK E2E tests, ARM)

If you have any questions or requests, please contact @zhikunyao.

@sre-ci-robot
Copy link
Copy Markdown
Contributor

✅ CI Loop Results 3a0651f

Stage Result Duration Tests
✅ Build SUCCESS 11.8min -

Total: 16min | Pipeline | Artifacts

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 9, 2026

Codecov Report

❌ Patch coverage is 82.83582% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.83%. Comparing base (0a689a7) to head (795f74b).
⚠️ Report is 35 commits behind head on master.

Files with missing lines Patch % Lines
internal/core/src/exec/operator/FilterBitsNode.cpp 30.76% 9 Missing ⚠️
internal/core/src/query/ExecPlanNodeVisitor.cpp 44.44% 5 Missing ⚠️
internal/core/src/exec/QueryContext.h 25.00% 3 Missing ⚠️
...ternal/core/src/segcore/ChunkedSegmentSealedImpl.h 0.00% 2 Missing ⚠️
internal/core/src/segcore/SegmentInterface.h 0.00% 2 Missing ⚠️
internal/util/segcore/plan.go 33.33% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           master   #48883       +/-   ##
===========================================
- Coverage   84.44%   77.83%    -6.62%     
===========================================
  Files         642     2150     +1508     
  Lines      101106   353267   +252161     
===========================================
+ Hits        85382   274969   +189587     
- Misses      15724    69806    +54082     
- Partials        0     8492     +8492     
Components Coverage Δ
Client 79.25% <ø> (∅)
Core 84.44% <82.20%> (-0.01%) ⬇️
Go 76.04% <87.50%> (∅)
Files with missing lines Coverage Δ
internal/core/src/exec/operator/FilterBitsNode.h 63.63% <ø> (ø)
internal/core/src/query/ExecPlanNodeVisitor.h 100.00% <100.00%> (ø)
internal/core/src/segcore/ExprFilterCache.h 100.00% <100.00%> (ø)
internal/core/src/segcore/SegcoreConfig.h 80.95% <100.00%> (+0.46%) ⬆️
internal/core/src/segcore/SegmentInterface.cpp 78.52% <ø> (ø)
internal/core/src/segcore/segment_c.cpp 45.00% <100.00%> (ø)
internal/core/unittest/test_expr_filter_cache.cpp 100.00% <100.00%> (ø)
...ternal/core/unittest/test_utils/c_api_test_utils.h 96.82% <ø> (ø)
internal/querynodev2/delegator/delegator.go 84.65% <100.00%> (ø)
...ternal/querynodev2/delegator/delegator_twostage.go 84.28% <100.00%> (ø)
... and 8 more

... and 1501 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sre-ci-robot
Copy link
Copy Markdown
Contributor

✅ CI Loop Results 3a0651f

Stage Result Duration Tests
✅ Build SUCCESS 8.0min -

Total: 12min | Pipeline | Artifacts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
@sparknack
Copy link
Copy Markdown
Contributor Author

@sre-ci-robot /retest

@sparknack
Copy link
Copy Markdown
Contributor Author

/ci-rerun-code-check

@sre-ci-robot
Copy link
Copy Markdown
Contributor

✅ CI Loop Results 739c01c

Stage Result Duration Tests
✅ Build SUCCESS 8.7min -

Total: 13min | Pipeline | Artifacts

@sparknack
Copy link
Copy Markdown
Contributor Author

@sre-ci-robot /ci-rerun-code-check

@sparknack
Copy link
Copy Markdown
Contributor Author

/ci-rerun-code-check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
@sre-ci-robot sre-ci-robot added size/XXL Denotes a PR that changes 1000+ lines. and removed size/L Denotes a PR that changes 100-499 lines. labels Apr 13, 2026
@sre-ci-robot sre-ci-robot added low-code-coverage add test-label from zhikun, diff coverage > 80% and removed low-code-coverage add test-label from zhikun, diff coverage > 80% labels Apr 13, 2026
@sparknack
Copy link
Copy Markdown
Contributor Author

/ci-rerun-e2e-default

@mergify mergify Bot added the ci-passed label Apr 13, 2026
@zhengbuqian
Copy link
Copy Markdown
Collaborator

/hold

let's try reuse the existing expr cache

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/compilation area/internal-api ci-passed dco-passed DCO check passed. do-not-merge/hold kind/enhancement Issues or changes related to enhancement size/XXL Denotes a PR that changes 1000+ lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants