Skip to content

[feature](be) Add SNII inverted index storage format#64909

Open
airborne12 wants to merge 86 commits into
apache:masterfrom
airborne12:snii
Open

[feature](be) Add SNII inverted index storage format#64909
airborne12 wants to merge 86 commits into
apache:masterfrom
airborne12:snii

Conversation

@airborne12

@airborne12 airborne12 commented Jun 27, 2026

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary:
This PR integrates the SNII inverted index storage format into Doris as a separate storage-format path. SNII index files are written and read through the SNII implementation instead of falling through to the existing inverted-index storage stack, while analyzer usage remains shared where needed.

The change adds SNII-specific handling in index file reader/writer paths, preserves Doris IO context during SNII reads, bounds expanding prefix/regexp/wildcard/phrase-prefix queries before materializing all matching terms, and skips old inverted-index compaction/drop-index handling for SNII files. Unsupported SNII paths are rejected explicitly, including BKD-backed non-string indexes, ANN indexes, and BUILD INDEX.

The PR also adds inverted-index IO profile metrics for comparing real remote index scan behavior, then optimizes SNII high-df term and phrase hot paths found during cloud_sim E2E benchmarking. CPU profiles showed phrase execution dominated by docid conjunction, PFOR PRX decode, selective PRX CSR compaction, and exact two-term phrase verification overhead, not remote I/O. The optimization streams eligible term/prefix/regexp/wildcard results directly into Roaring, emits dense docid windows as ranges, carries PRX doc ordinal context through phrase execution, builds selected PRX count ranges during PFOR decode, skips redundant final-candidate filtering, adds sparse galloping docid conjunction paths, caps reserve sizes to the maximum possible match count, uses a chunk-level merge verifier for non-repeated two-term phrases, adds low-bit PFOR unpack fast paths, and uses bounded-span bitset/rank intersection for phrase candidate ordinal mapping.

Hotspot analysis for MATCH_PHRASE 'failed order' on the 10B cloud_sim dataset:

  • Before the final CPU work, pprof showed intersect_window_candidates_with_ordinals 20.2%, pfor_decode 16.3%, selected PFOR range building 11.5%, and PRX position materialization 11.5%.
  • After low-bit PFOR unpack fast paths, pfor_decode dropped to 6.6%, while docid conjunction became the dominant remaining self-CPU at 20.1%.
  • After bounded-span bitset/rank intersection, docid conjunction self-CPU dropped to 12.9%. IO bytes and serial read rounds were unchanged, confirming this was CPU-side algorithmic work rather than cache or remote-IO variance.

Representative cloud_sim cold benchmark on the 10B textbench dataset:

  • OP_term_high_df: V3 wall 3113.411 ms / CPU 22.27 s / HWM 6464 MB / read 819.39 MB / serial rounds 209.764K; SNII wall 2963.013 ms / CPU 19.62 s / HWM 3563 MB / read 579.32 MB / serial rounds 1.664K.
  • MATCH_PHRASE 'failed order': V3 wall 6434.967 ms / CPU 69.63 s / HWM 5561 MB / read 3.05 GB / serial rounds 799.466K; SNII baseline wall 5480.060 ms / CPU 48.07 s / scanner 45.607 s / read 2.92 GB / remote 2.64 GB / serial rounds 2.272K; SNII after final CPU optimization wall 5305.507 ms / CPU 41.68 s / scanner 39.231 s / read 2.92 GB / remote 2.64 GB / serial rounds 2.272K.
  • MATCH_PHRASE_PREFIX 'failed ord': V3 wall 7231.285 ms / CPU 82.25 s / HWM 5541 MB / read 3.07 GB / serial rounds 803.965K; SNII baseline wall 5688.971 ms / CPU 49.95 s / scanner 47.404 s / read 3.02 GB / remote 2.69 GB / serial rounds 2.353K; SNII after final CPU optimization wall 5189.219 ms / CPU 43.57 s / scanner 41.221 s / read 3.02 GB / remote 2.69 GB / serial rounds 2.353K.

Release note

Add SNII inverted index storage format and reject unsupported BKD, ANN, and BUILD INDEX operations for SNII.

Check List (For Author)

  • Test

    • Regression test
      • ./bootstrap.sh run -- --run -d inverted_index_p0/storage_format -s test_storage_format_snii -forceGenOut
      • ./bootstrap.sh run -- --run -d inverted_index_p0/storage_format -s test_storage_format_snii
    • Unit Test
      • ./run-fe-ut.sh --run org.apache.doris.nereids.trees.plans.commands.IndexDefinitionTest,org.apache.doris.alter.IndexChangeJobTest
      • ./run-be-ut.sh --run --filter='SniiPhraseQueryTest.*:SniiTermQueryTest.*:SniiPrxPodTest.*:SniiPforTest.*'
    • Manual test (add detailed scripts or steps below)
      • ./build.sh --be --fe -j 192
      • ./build.sh --be -j 192
      • ./build-support/clang-format.sh be/src/storage/index/snii/core/src/encoding/pfor.cpp be/src/storage/index/snii/core/src/query/docid_conjunction.cpp be/test/storage/index/snii_query_test.cpp
      • ./build-support/check-format.sh be/src/storage/index/snii/core/src/encoding/pfor.cpp be/src/storage/index/snii/core/src/query/docid_conjunction.cpp be/test/storage/index/snii_query_test.cpp
      • git diff --check
      • build-support/run-clang-tidy.sh --build-dir be/build_Release
      • Deployed Release BE to /mnt/disk1/jiangkai/cloud_sim/jiangkai_test, verified current-user MS/recycler/FE/BE processes, and verified SHOW BACKENDS Alive=true.
      • Ran support_phrase MATCH_PHRASE and MATCH_PHRASE_PREFIX smoke queries against textbench_10b_perf.otel10b_phrase40_snii.
      • Ran cloud_sim cold E2E benchmarks and pprof analysis for OP_term_high_df, PH5_phrase_failed_order, and PP5_phrase_prefix_failed.
      • Final PH5/PP5 run: /mnt/disk15/jiangkai/textbench/runs/20260628_phrase_cpu_opt_final_verified.
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

airborne12 added a commit to airborne12/apache-doris that referenced this pull request Jun 27, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#64909

Problem Summary: SNII phrase and phrase-prefix queries spent most CPU in docid intersection, selective PRX/PFOR decode, and position verification. This change avoids generating PRX ordinals for full on-disk windows so the reader can use the full CSR path, folds selective PRX count validation into selected-range construction, removes hot-loop overflow helper calls from two-term phrase matching, and routes single-tail phrase-prefix queries through the streaming phrase path to avoid materializing all expected tail positions. On the 10B cloud_sim PP5 cold query, SNII BE CPU improved from 72.20s to 63.29s and HWM dropped from 20.26GB to 7.08GB.

### Release note

None

### Check List (For Author)

- Test: Unit Test and Manual test
    - Unit Test: ./run-be-ut.sh --run --filter=SniiPhraseQueryTest.*:SniiPrxPodTest.*
    - Static check: build-support/check-format.sh; git diff --check
    - Manual test: ./build.sh --be -j 192
    - Manual test: cloud_sim cold query benchmark for PH5/PP5 via /mnt/disk15/jiangkai/textbench/cold_query_bench.sh
- Behavior changed: No
- Does this need documentation: No
airborne12 added a commit to airborne12/apache-doris that referenced this pull request Jun 28, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#64909

Problem Summary: SNII phrase queries over high-df terms were CPU-bound in PFOR unpacking and docid conjunction ordinal mapping. PH5/PP5 profiling on the 10B cloud_sim dataset showed pfor_decode and intersect_window_candidate_range_with_ordinals as top self CPU consumers while remote bytes and serial read rounds stayed fixed. This change adds low-bit PFOR unpack fast paths for common widths 3/5/6/7 and a bounded-span bitset/rank intersection path that preserves PRX doc ordinals for 16K-doc windows. The optimized path keeps the on-disk format unchanged and reduces CPU in the cold cloud_sim phrase benchmark: PH5 BE CPU 48.07s -> 41.68s, PP5 BE CPU 49.95s -> 43.57s.

### Release note

None

### Check List (For Author)

- Test: Unit Test / Manual test
    - build-support/clang-format.sh be/src/storage/index/snii/core/src/encoding/pfor.cpp be/src/storage/index/snii/core/src/query/docid_conjunction.cpp be/test/storage/index/snii_query_test.cpp
    - build-support/check-format.sh be/src/storage/index/snii/core/src/encoding/pfor.cpp be/src/storage/index/snii/core/src/query/docid_conjunction.cpp be/test/storage/index/snii_query_test.cpp
    - git diff --check
    - build-support/run-clang-tidy.sh --build-dir be/build_Release
    - ./run-be-ut.sh --run --filter='SniiPhraseQueryTest.*:SniiTermQueryTest.*:SniiPrxPodTest.*:SniiPforTest.*'
    - ./build.sh --be -j 192
    - cloud_sim deploy/start BE and PH5/PP5 cold phrase benchmark under /mnt/disk15/jiangkai/textbench/runs/20260628_phrase_cpu_opt_final_verified
- Behavior changed: No
- Does this need documentation: No
Comment thread be/src/snii/common/status.h Outdated
// Reserve docids/freqs by ntok (an upper bound on the doc count: ntok >= ndocs).
// The doc count is not stored separately to keep Term compact; since the corpus
// is freq~1 per (term, doc), ntok ~= ndocs so the over-reserve is negligible.
tp.docids.reserve(t.ntok);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is allocating the entire ntok size of memory directly to docids and freqs too aggressive? Wouldn't it be better to use an nDocs field in the Term to record the doc freq?

### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Doris only routed inverted index files through the existing V1/V2 storage implementations. This change adds SNII as an independent inverted index storage format, copies the SNII core reader/writer/query implementation into BE, and branches the Doris index file reader/writer paths so SNII reads, writes, queries, and null bitmap handling go through SNII code. SNII reuses Doris analyzer integration only; it does not route SNII storage through the existing CLucene directory/compound reader paths. SNII currently supports string and array string inverted indexes, while numeric/BKD indexes are rejected for this format until BKD support is implemented.

### Release note

Add SNII as an inverted index storage format for string inverted indexes. BKD indexes are not supported with SNII yet.

### Check List (For Author)

- Test: Build
    - `./build.sh --be`
    - `./build.sh --fe`
    - `build-support/clang-format.sh`
    - `build-support/check-format.sh`
    - `build-support/run-clang-tidy.sh --build-dir be/build_Release` attempted; it failed because clang-tidy could not resolve `stddef.h` in this toolchain and also reported pre-existing unrelated diagnostics.
- Behavior changed: Yes. Tables using `inverted_index_storage_format=SNII` route string inverted index storage/query/null handling through SNII and reject BKD indexes.
- Does this need documentation: Yes. No doc PR yet.
### What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary: Add a focused regression case for the SNII inverted index storage format. The test creates a string inverted index with inverted_index_storage_format=SNII, verifies MATCH_ANY, MATCH_ALL, MATCH_PHRASE, and NULL bitmap behavior, and validates that numeric/BKD inverted index creation is rejected for SNII.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - bash /mnt/disk1/jiangkai/cloud_sim/bootstrap.sh run -- --run -d inverted_index_p0/storage_format -s test_storage_format_snii -genOut
    - bash /mnt/disk1/jiangkai/cloud_sim/bootstrap.sh run -- --run -d inverted_index_p0/storage_format -s test_storage_format_snii
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: This change completes the SNII inverted index storage-format split by routing SNII reads and writes through the SNII implementation, preserving Doris IO context during SNII file reads, bounding expanding queries before materializing all prefix terms, and rejecting unsupported SNII operations such as BKD-backed indexes, ANN indexes, and BUILD INDEX. It also avoids applying old CLucene index-compaction/drop-index paths to SNII files and adds focused FE and regression coverage for unsupported paths.

### Release note

SNII inverted index storage format rejects unsupported BKD, ANN, and BUILD INDEX operations.

### Check List (For Author)

- Test:
    - Build: ./build.sh --be --fe -j 192
    - Build: ./build.sh --be -j 192
    - Unit Test: ./run-fe-ut.sh --run org.apache.doris.nereids.trees.plans.commands.IndexDefinitionTest,org.apache.doris.alter.IndexChangeJobTest
    - Regression test: ./bootstrap.sh run -- --run -d inverted_index_p0/storage_format -s test_storage_format_snii -forceGenOut; ./bootstrap.sh run -- --run -d inverted_index_p0/storage_format -s test_storage_format_snii
    - Format: ./build-support/clang-format.sh; ./build-support/check-format.sh; git diff --check
    - Static Analysis: ./build-support/run-clang-tidy.sh and ./build-support/run-clang-tidy.sh --build-dir be/build_Release attempted; failed because clang-tidy could not resolve system stddef.h and also reported existing large-function/NOLINT diagnostics outside the safe scope of this SNII integration.
- Behavior changed: Yes. SNII explicitly rejects unsupported BKD/ANN/BUILD INDEX paths instead of falling through to non-SNII index handling.
- Does this need documentation: No
Issue Number: None

Related PR: None

Problem Summary: SNII performance validation in cloud mode needs comparable IO observability against the existing CLucene/V3 inverted index path. Before this change, SNII opened remote index files without the same file-cache options as V3 and only part of the IO context reached SNII/CLucene readers, so query profiles could not compare logical requested index bytes, physical index reads, and serial read rounds. This change routes SNII index file opens through Doris file-cache options, propagates copied inverted-index IO context through SNII reads, records request/read bytes and read round counters for both SNII and CLucene index readers, and exposes those counters in the file-cache profile reporter.

SNII and V3 inverted index scans now expose additional IO profile counters for request bytes, physical read bytes, range read count, and serial read rounds.

- Test:
    - Unit Test: ./run-be-ut.sh --clean --run --filter='DorisSniiFileReaderTest.*:DorisFSDirectoryTest.FSIndexInputReadInternalRecordsIndexIOStatsAndContext:FileCacheProfileReporterTest.*' -j "192"
    - Unit Test: ./run-be-ut.sh --run --filter='DorisSniiFileReaderTest.*:DorisFSDirectoryTest.FSIndexInputReadInternalRecordsIndexIOStatsAndContext:FileCacheProfileReporterTest.*' -j "192"
    - Format: build-support/clang-format.sh; build-support/check-format.sh; git diff --check
    - Static Analysis: build-support/run-clang-tidy.sh --build-dir be/ut_build_ASAN attempted; failed because clang-tidy could not resolve system stddef.h and also reported existing large-function/C-header/NOLINT diagnostics outside this change. Clear new SNII adapter style warnings were fixed.
- Behavior changed: Yes. SNII remote index file reads now use the same Doris file-cache reader options as V3 when file cache is enabled, and both SNII/V3 report additional profile counters.
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: SNII phrase and phrase-prefix queries spent most CPU time re-scanning phrase candidate docids for every PRX chunk and allocating per-doc expected tail position vectors. On the 10B TextBench cloud benchmark, MATCH_PHRASE 'failed order' took 253.0s wall / 3942.9 CPU-s and MATCH_PHRASE_PREFIX 'failed ord' took 438.3s wall / 6939.5 CPU-s before this optimization. The fix starts PRX candidate filtering from the chunk's first docid, keeps an all-selected fast path, stores expected tail positions in flat CSR-style arrays, and uses a single exact-term fast path for phrase-prefix expected tail positions. The same benchmark now runs in about 3.8s / 59.3 CPU-s for phrase and 3.9s / 61-62 CPU-s for phrase-prefix.

### Release note

None

### Check List (For Author)

- Test:
    - Unit Test: ./run-be-ut.sh --run --filter=SniiPhraseQueryTest.*
    - Manual test: release BE build and cloud_sim E2E TextBench phrase benchmark
    - Static check: git diff --check; build-support/run-clang-tidy.sh --build-dir be/build_Release passed changed lines in phrase_query.cpp, while the new BE UT source is blocked by a local libstdc++ _POSIX_SEM_VALUE_MAX toolchain header error.
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: SNII MATCH_PHRASE in cloud mode spent most CPU in selective PRX/PFOR decode, candidate ordinal materialization, and generic two-term position checks. This change removes per-doc ordinal Status overhead, uses selected PRX ranges to compact dense PFOR decodes, decodes sparse PFOR runs through a stack buffer, and adds a two-term phrase merge path. In cloud_sim PH5 on textbench_10b_perf.otel10b_phrase40_snii, BE CPU is now about 47.67s on average with SQL and inverted-index query cache disabled, down from roughly 55-59s observed before these optimizations.

### Release note

None

### Check List (For Author)

- Test: Unit Test and Manual test
    - Unit Test: ./run-be-ut.sh --run --filter=SniiPhraseQueryTest.*:SniiPrxPodTest.*
    - Build: ./build.sh --be -j 192
    - Manual test: deployed BE to cloud_sim and ran PH5 benchmark under /mnt/disk15/jiangkai/textbench/runs/20260628_phrase_cpu_opt_final_refactor_nocache
    - Static check: git diff --check; build-support/run-clang-tidy.sh --build-dir be/build_Release attempted but failed because the local clang/GCC sysroot cannot resolve stddef.h
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#64909

Problem Summary: SNII phrase and phrase-prefix queries spent most CPU in docid intersection, selective PRX/PFOR decode, and position verification. This change avoids generating PRX ordinals for full on-disk windows so the reader can use the full CSR path, folds selective PRX count validation into selected-range construction, removes hot-loop overflow helper calls from two-term phrase matching, and routes single-tail phrase-prefix queries through the streaming phrase path to avoid materializing all expected tail positions. On the 10B cloud_sim PP5 cold query, SNII BE CPU improved from 72.20s to 63.29s and HWM dropped from 20.26GB to 7.08GB.

### Release note

None

### Check List (For Author)

- Test: Unit Test and Manual test
    - Unit Test: ./run-be-ut.sh --run --filter=SniiPhraseQueryTest.*:SniiPrxPodTest.*
    - Static check: build-support/check-format.sh; git diff --check
    - Manual test: ./build.sh --be -j 192
    - Manual test: cloud_sim cold query benchmark for PH5/PP5 via /mnt/disk15/jiangkai/textbench/cold_query_bench.sh
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: SNII high-df term and phrase queries spent avoidable CPU in vector-to-Roaring materialization, dense docid expansion, selected PRX range construction, repeated final-candidate filtering, and sorted docid conjunction. The CPU profile showed phrase execution dominated by docid conjunction, PFOR PRX decode, and selective PRX CSR compaction instead of remote I/O. This change streams eligible term, prefix, regexp, and wildcard query results directly into Roaring, emits dense docid windows as ranges, carries PRX doc ordinal context through phrase execution, builds selected PRX count ranges during PFOR decode, skips redundant final-candidate filtering, and adds sparse galloping paths for docid conjunction. It also caps conjunction reserve sizes to the maximum possible match count and refactors the SNII reader query dispatch to keep the storage reader control flow smaller.

### Release note

None

### Check List (For Author)

- Test: Unit Test / Manual test
    - Unit Test: ./run-be-ut.sh --run --filter=SniiPhraseQueryTest.*:SniiTermQueryTest.*:SniiPrxPodTest.*
    - Manual test: ./build.sh --be -j 192
    - Manual test: deployed BE to cloud_sim and ran support_phrase MATCH_PHRASE smoke query
    - Manual test: cloud_sim cold benchmark for OP_term_high_df, PH5_phrase_failed_order, and PP5_phrase_prefix_failed
    - Static check: git diff --check; build-support/check-format.sh
    - Static check: clang-tidy was attempted with build-support/run-clang-tidy.sh --build-dir be/build_Release, but this environment failed before useful changed-line validation with missing stddef.h/toolchain include errors and pre-existing full-file warnings.
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: SNII phrase queries on the 10B cloud benchmark spent most CPU in PRX position decode, posting cursor iteration, and docid conjunction. This change adds a two-term phrase streaming path, uses an adjacent-pair prefilter for multi-term phrase verification, reuses candidate ranges during docid conjunction, and adds low bit-width PFOR unpack paths for common PRX count and delta widths. A near-dense ordinal shortcut was tested and removed because it regressed the PH5 and PP5 phrase cases. In the cloud_sim 10B cold benchmark, PH5 improved from 6181 ms wall time and 60.22 s BE CPU to 5794 ms wall time and 55.43 s BE CPU; PP5 improved from 6211 ms wall time and 59.82 s BE CPU to 6038 ms wall time and 56.26 s BE CPU. PH5 pprof shows pfor_decode self CPU reduced to about 11.4% after the low bit-width fast paths.

### Release note

None

### Check List (For Author)

- Test:
    - Unit Test: ./run-be-ut.sh --run --filter='SniiPforTest.*:SniiPhraseQueryTest.*:SniiTermQueryTest.*:SniiPrxPodTest.*'
    - Manual test: ./build.sh --be -j 192
    - Manual test: cloud_sim PH5/PP5 cold benchmark at /mnt/disk15/jiangkai/textbench/runs/20260628_phrase_cpu_final_pfor_next_cold
    - Manual test: cloud_sim PH5 pprof at /mnt/disk15/jiangkai/textbench/runs/20260628_phrase_final_pfor_next_pprof
    - Static Check: build-support/clang-format.sh, build-support/check-format.sh, and build-support/run-clang-tidy.sh --build-dir be/build_Release
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: SNII phrase queries on the 10B cloud benchmark still spent the largest CPU share in docid/ordinal intersection before PRX verification. The hot path had to intersect dense or near-dense candidate windows with term docids and produce PRX doc ordinals. This change adds a candidate-span fast path that directly accepts all term docids when candidates continuously cover the term span, adds dense/near-dense ordinal mapping for term spans with few missing docs, and fixes mixed dense/non-dense window output ordering by batching window work and flushing in original order. In cloud_sim PH5/PP5 cold benchmark, PH5 improved from 5794 ms wall and 55.43 s BE CPU to 5702 ms wall and 53.55 s BE CPU; PP5 kept similar wall time and reduced BE CPU from 56.26 s to 55.21 s. The inverted index read bytes, remote bytes, cache bytes, serial rounds, and IO counts stayed unchanged, so the improvement is from CPU-side algorithm work rather than reduced remote reads. A bulk dense append variant was tested and reverted because it regressed PH5/PP5.

### Release note

None

### Check List (For Author)

- Test:
    - Unit Test: ./run-be-ut.sh --run --filter='SniiPforTest.*:SniiPhraseQueryTest.*:SniiTermQueryTest.*:SniiPrxPodTest.*'
    - Manual test: ./build.sh --be -j 192
    - Manual test: cloud_sim PH5/PP5 cold benchmark at /mnt/disk15/jiangkai/textbench/runs/20260628_phrase_final_cover_span_refactor_cold
    - Manual test: cloud_sim PH5 pprof at /mnt/disk15/jiangkai/textbench/runs/20260628_phrase_final_cover_span_refactor_pprof
    - Static Check: build-support/clang-format.sh, build-support/check-format.sh, git diff --check
    - Static Check: build-support/run-clang-tidy.sh --build-dir be/build_Release failed because the local ldb clang-tidy toolchain could not find stddef.h while parsing system headers
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: SNII phrase verification still spent CPU in per-candidate cursor/status handling for exact two-term phrases. Profiles showed PostingCursor::next and positions handling in the hot path while IO metrics stayed unchanged. This change reuses a shared PRX chunk decoder and adds a two-term chunk merge path for non-repeated phrases so overlapping chunks decode once and docids are verified with a linear merge. Repeated-term phrases still use the existing streaming path, and multi-term streaming is split into smaller helpers. On 10B textbench cold cloud_sim runs, PH5 CPU dropped from 53.55s to 48.07s and PP5 CPU dropped from 55.21s to 49.95s with identical IO bytes.

### Release note

None

### Check List (For Author)

- Test:
    - Unit Test: ./run-be-ut.sh --run --filter='SniiPhraseQueryTest.*:SniiTermQueryTest.*:SniiPrxPodTest.*:SniiPforTest.*'
    - Manual test: ./build.sh --be -j 192
    - Manual test: cloud_sim BE redeploy and smoke MATCH_PHRASE / MATCH_PHRASE_PREFIX
    - Benchmark: textbench 10B cold PH5/PP5 comparison
    - Static check: build-support/clang-format.sh, build-support/check-format.sh, git diff --check; build-support/run-clang-tidy.sh --build-dir be/build_Release attempted but blocked by local clang-tidy system header resolution where stddef.h is not found.
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#64909

Problem Summary: SNII phrase queries over high-df terms were CPU-bound in PFOR unpacking and docid conjunction ordinal mapping. PH5/PP5 profiling on the 10B cloud_sim dataset showed pfor_decode and intersect_window_candidate_range_with_ordinals as top self CPU consumers while remote bytes and serial read rounds stayed fixed. This change adds low-bit PFOR unpack fast paths for common widths 3/5/6/7 and a bounded-span bitset/rank intersection path that preserves PRX doc ordinals for 16K-doc windows. The optimized path keeps the on-disk format unchanged and reduces CPU in the cold cloud_sim phrase benchmark: PH5 BE CPU 48.07s -> 41.68s, PP5 BE CPU 49.95s -> 43.57s.

### Release note

None

### Check List (For Author)

- Test: Unit Test / Manual test
    - build-support/clang-format.sh be/src/storage/index/snii/core/src/encoding/pfor.cpp be/src/storage/index/snii/core/src/query/docid_conjunction.cpp be/test/storage/index/snii_query_test.cpp
    - build-support/check-format.sh be/src/storage/index/snii/core/src/encoding/pfor.cpp be/src/storage/index/snii/core/src/query/docid_conjunction.cpp be/test/storage/index/snii_query_test.cpp
    - git diff --check
    - build-support/run-clang-tidy.sh --build-dir be/build_Release
    - ./run-be-ut.sh --run --filter='SniiPhraseQueryTest.*:SniiTermQueryTest.*:SniiPrxPodTest.*:SniiPforTest.*'
    - ./build.sh --be -j 192
    - cloud_sim deploy/start BE and PH5/PP5 cold phrase benchmark under /mnt/disk15/jiangkai/textbench/runs/20260628_phrase_cpu_opt_final_verified
- Behavior changed: No
- Does this need documentation: No
…SR decode

decode_payload_csr_selective (the .prx position reader used once a
candidate docid set is known) previously decoded EVERY doc's position
deltas even for non-candidate docs, only to advance the sequential CSR
cursor, then discarded them (if !selected continue). Profiling a
multi-word phrase-prefix ('GET images sp*') showed ~40% of the query
CPU in this varint decode -- with a sparse candidate set most decoded
positions were thrown away.

New ByteSource::skip_varints(count) advances past N varints by scanning
only continuation bits (one branch per byte, no shift/accumulate/store/
per-value Status). decode_payload_csr_selective uses it for non-selected
docs. Read-side only: no format, disk, or import change, and every
phrase/phrase-prefix operator that narrows to candidates before reading
positions gets faster (no operator regresses).

Result (cloud_sim, 'GET images sp*' SNII vs V3 wall):
  warm 1507->1284ms (1.61x->1.31x slower), cold 1889->1593 (1.58x->1.32x).
  Full trajectory from the campaign start: 3.7x/3.15x -> 1.31x/1.32x.
  agentlogs 'token estimate co*' stays FASTER (1.28x warm / 1.06x cold).

UT: 767/767 incl. 2 new SkipVarints tests (skip advances identically to
decode across 1-5 byte encodings; truncation fails).
The CSR position reader decoded each varint through the out-of-line
get_varint32 -> get_varint64 -> decode_varint64 chain (per-value Status,
no fast path), and read each doc's pos_count header the same way. Both
dominate the phrase / phrase-prefix hot loop once positions are narrowed
to candidate docs.

- ByteSource::decode_delta_run(count, out): tight inline LEB128 decoder
  with a single-byte fast path that prefix-sums ascending position deltas
  directly into the flat output; replaces the inner decode loop in
  decode_payload_csr and decode_payload_csr_selective.
- ByteSource::get_varint32_fast(v): inline single-byte fast path for the
  per-doc pos_count header (falls back to get_varint32 for multi-byte).

Warm httplogs 'GET images sp*' phrase-prefix ii_filter CPU 9483 -> 6972
(-26%); no on-disk format change; all SNII decode paths share the win.
Unit tests: decode_delta_run prefix-sum/append/truncation equivalence,
get_varint32_fast vs slow-path equivalence, skip_varints long-run.
…c flag

New off-by-default mutable config inverted_index_read_bypass_file_cache.
When set, inverted-index file readers (both SNII and CLucene) open with
NO_CACHE and issue precise S3 range GETs, bypassing the 1MiB
FILE_BLOCK_CACHE -- WITHOUT touching the global enable_file_cache, so
cloud mode (which requires it) still boots.

Diagnostic-only: it isolates the block-cache read amplification and the
serial-round cost on the direct object-store path (a direct-vs-direct
engine comparison the block cache otherwise masks). Warm queries lose the
local cache under this flag, so it is a measurement knob, not a
production setting. Read-side only; V3/CLucene and SNII both honor it via
the per-open cache_type.
…ccumulation

An exact reserve(size()+count) per NULL run (writer add_nulls) or per docid
range (query VectorDocIdSink::append_range) caps capacity at "just enough",
so the NEXT append reallocates and memcpys the whole accumulated array:
O(runs x array_bytes) total memcpy. On an agentlogs full compaction segment
(12.4M rows, 22% interleaved nulls) this meant TBs of memcpy per tablet --
the compaction ran 8x+ slower than V3 (whose add_nulls is a roaring
addRange) and peaked at 198 GB RSS; post-fix it settles at 2.6x / 18.7 GB.

Grow by max(need, 2 * capacity) instead (one reallocation per large run,
O(count) amortized), mirror _null_docids capacity into the writer's
MemoryReporter (and through it the LOAD MemTracker) so a large
interleaved-null segment no longer accumulates untracked RSS, and pin the
growth policy with regression tests.
…n (opt-in)

New mBool snii_bigram_defer_build_to_compaction (default false): a direct,
non-ARRAY load (stream/broker load, DataWriteType::TYPE_DIRECT) skips feeding
the hidden adjacent-pair bigram tokens AND the bigram sentinel -- measured at
-50.7% (wikipedia) / -32% (agentlogs) of import index CPU -- and persists a
resident per-index meta flag (kPhraseBigramsDeferred) so phrase readers on
such fresh segments skip impossible pair-dict probes (a per-tail lookup for
MATCH_PHRASE_PREFIX) and go straight to the full-fidelity
positions-verification fallback: identical results, slower, until compaction
re-feeds every token and rebuilds the bigram index at no extra compaction
cost (measured equal wall/CPU vs a regular segment's full compaction).

Compatibility: old readers keep the omitted-sentinel fallback contract (plus
the persisted df-prune thresholds as a redundant trigger); new readers on old
segments see the flag absent and behave unchanged; docs-only and ARRAY
indexes never defer. Plumbed via ColumnWriterOptions.is_direct_load ->
IndexColumnWriter::set_direct_load(), forwarded unconditionally by the column
writer right after create(), captured once per writer behind an explicit
latch (a late call is logged and ignored). The add_snii_index mid-load
prune-flip flush guard exempts deferred segments (their bigram diet is
provably inert). NOTE: compaction is the only rebuild mechanism -- see the
perf-cliff disclosure in config.h before enabling.

Verified: E2E fresh/compacted phrase and phrase-prefix counts equal V3 on
wikipedia/agentlogs (real S3 cloud mode); writer/wiring/e2e gtests cover
capture-once config flips, byte-identity of every non-deferring combination,
flag/postings lifecycle coherence, both segment writers, and variant
subcolumn propagation; SNII UT 788/788.
… prx tier

Two write-CPU cuts backed by a 4-corpus evaluation (wikipedia 1M / httplogs
247M / agentlogs 99M / textbench 1B, cloud mode, real S3; effects isolated
with same-binary config-only A/B -- back-to-back pairs or ABAB with the
warm-up pair discarded):

1. Default snii_dict_block_zstd_level and snii_prx_zstd_level from 9 to 3.
   The delta+varint-encoded dict/prx payloads are high-entropy, so level 9's
   extra search buys almost no ratio: settled index grows only +0.6%..+6.3%
   (whole table +0.3%..+1.9%, agentlogs 0) while import CPU drops 4-18%
   total / 6-37% of the index share (httplogs -290s, agentlogs -204s,
   textbench -1300s+-500, wikipedia -89s+-13) and full-compaction CPU falls
   8-24% (rebuild re-compression). Settled cold-query latency is unchanged
   (interleaved A/B, phrase/prefix); counts equal V3 across the operator set.

2. New snii_prx_zstd_level_direct_load (default 3, clamp [3,19]): direct
   loads (stream/broker, captured once by set_direct_load alongside the
   bigram-defer decision) compress prx at the load tier while compaction /
   schema change / ADD INDEX keep snii_prx_zstd_level. Inert at the new
   defaults; it lets size-critical deployments raise the compaction level
   (e.g. 9) and keep loads cheap, since compaction rewrites every segment --
   settled data is byte-for-byte unaffected by the tier.

add_snii_index now takes a SniiAddIndexOptions struct (phrase_bigrams_deferred
+ is_direct_load) instead of a bare bool. New gtests pin the tier contract:
identical answers with a strict size delta, non-direct paths byte-identical
whatever the tier value, flush-read level semantics, and clamping. SNII UT
792/792.
…I buffer

Drop the materializing token lane (get_analyse_result building a per-row
vector<TermInfo> with one heap std::string per token, immediately re-copied
into the SPIMI intern arena): SniiIndexColumnWriter now walks the CLucene
TokenStream itself and feeds each token to
SpimiTermBuffer::add_token_returning_id as a string_view over the token
buffer -- one copy total, into the arena. Tokenization semantics are mirrored
exactly, including the subtle one: an empty token's position increment is
dropped with the token. The keyword (non-analyzed) lane streams the value
slice the same way.

Byte-identity is pinned by new golden-byte tests
(snii_writer_golden_bytes_test.cpp): a fixed edge-case corpus (empty value,
punctuation-only row, >ignore_above value, unicode/mixed text, repeated
terms, multi-batch adds, interleaved null runs) written through the
production stack must reproduce recorded FNV-1a-64 digests for english /
unicode / keyword indexes -- harvested from the pre-change path and verified
deterministic across processes.

Measured with deploy-alternating binary ABAB x3 (idle machine, per-leg
warm-up import discarded): import CPU wikipedia -7..12%, httplogs -3..10%,
all six pairs the same direction; freshly written segments answer the
8-operator set count-equal to V3. SNII UT 795/795.
Restore the _no_need_read_key_data eligible/wrapper split that the G03
conflict resolution collapsed, and drop the _vir_cid_to_idx_in_block clause
from the count-emit shortcut facts (upstream removed the member; the
virtual-column expr map alone carries the eligibility signal now).
Flip snii_bigram_defer_build_to_compaction's default to true. The 4-corpus
write-parity campaign measured the deferral at -3.5%..-35% of import CPU
(wikipedia -543s, textbench -1006s, agentlogs -226s, httplogs -114s; same-
binary config ABAB x2, all eight pairs the same direction) with ZERO added
compaction cost -- SNII compaction rebuilds every token anyway, so the
load-time bigram build was duplicated work. With the deferral the textbench
(1B rows) import lands at index-CPU parity with V3 (1.02x).

Fresh direct-load segments answer phrase queries through the identical-
results positions fallback until compaction rebuilds the bigrams (resident
kPhraseBigramsDeferred flag routes readers past the impossible pair probes).
The config.h perf-cliff disclosure is reworded for the default-on world:
deployments whose compaction policy cannot cover lone-load rowsets should
disable this until the deferred-rowset compaction backstop lands.

SNII UT 795/795 and IndexStorage fixture family 64/64 with the new default
(every defer-sensitive test pins the config explicitly).
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.39% (1896/2450)
Line Coverage 64.45% (34072/52862)
Region Coverage 64.87% (17537/27032)
Branch Coverage 54.03% (9395/17390)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 54.55% (18/33) 🎉
Increment coverage report
Complete coverage report

### What problem does this PR solve?

Issue Number: None\n\nRelated PR: apache#64909\n\nProblem Summary: The PR build omitted the datasketches-cpp installation step from build.sh, so BE compilation could not find DataSketches/hll.hpp. Restore build.sh to origin/master, including the third-party setup and standard build flow.

### Release note\n\nNone

### Check List (For Author)\n\n- Test: Manual test\n    - source custom_env.sh && export DORIS_PARALLELISM=$(nproc) && ./build.sh --be -j${DORIS_PARALLELISM}\n- Behavior changed: No\n- Does this need documentation: No
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

1 similar comment
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29636 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit c35daaa4d41f08a9bdbe052ef3c4385f328088f1, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17620	4120	4096	4096
q2	2006	334	208	208
q3	10422	1492	832	832
q4	4759	473	338	338
q5	8306	866	591	591
q6	319	178	138	138
q7	933	871	627	627
q8	10669	1607	1547	1547
q9	5931	4469	4436	4436
q10	6799	1806	1521	1521
q11	499	354	319	319
q12	728	561	431	431
q13	18102	3800	2764	2764
q14	259	260	235	235
q15	q16	793	787	719	719
q17	1039	941	1062	941
q18	6909	5656	5468	5468
q19	1177	1337	998	998
q20	776	647	604	604
q21	5602	2571	2524	2524
q22	424	358	299	299
Total cold run time: 104072 ms
Total hot run time: 29636 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4420	4352	4343	4343
q2	278	315	213	213
q3	4596	4975	4374	4374
q4	2057	2158	1357	1357
q5	4548	4359	4342	4342
q6	280	298	157	157
q7	2284	1857	1626	1626
q8	2486	2276	2207	2207
q9	8299	7823	7800	7800
q10	4775	4698	4247	4247
q11	601	431	393	393
q12	778	777	542	542
q13	3302	3530	2910	2910
q14	299	304	275	275
q15	q16	730	731	645	645
q17	1365	1348	1462	1348
q18	7939	7379	7276	7276
q19	1150	1044	1077	1044
q20	2221	2221	1919	1919
q21	5248	4564	4408	4408
q22	527	447	407	407
Total cold run time: 58183 ms
Total hot run time: 51833 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 180137 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit c35daaa4d41f08a9bdbe052ef3c4385f328088f1, data reload: false

query5	4397	658	500	500
query6	482	239	226	226
query7	4877	609	330	330
query8	339	194	175	175
query9	8786	4054	4063	4054
query10	466	365	316	316
query11	5939	2345	2153	2153
query12	159	101	104	101
query13	1250	636	448	448
query14	6259	5296	4929	4929
query14_1	4318	4304	4309	4304
query15	220	204	181	181
query16	1073	488	473	473
query17	1157	739	607	607
query18	2653	478	353	353
query19	214	191	154	154
query20	111	109	115	109
query21	237	165	134	134
query22	13724	13623	13430	13430
query23	17438	16584	16255	16255
query23_1	16327	16349	16204	16204
query24	7620	1764	1285	1285
query24_1	1333	1301	1330	1301
query25	584	470	425	425
query26	1357	375	219	219
query27	2552	622	381	381
query28	4475	2016	1963	1963
query29	1106	645	502	502
query30	336	275	223	223
query31	1125	1097	984	984
query32	108	64	63	63
query33	544	332	265	265
query34	1159	1145	641	641
query35	784	795	675	675
query36	1408	1392	1229	1229
query37	151	111	99	99
query38	1879	1711	1672	1672
query39	931	910	891	891
query39_1	881	918	878	878
query40	260	163	178	163
query41	64	65	62	62
query42	90	90	91	90
query43	319	321	283	283
query44	1429	785	778	778
query45	195	195	181	181
query46	1049	1206	755	755
query47	2403	2356	2211	2211
query48	430	442	308	308
query49	582	441	308	308
query50	1038	419	326	326
query51	10585	10669	10666	10666
query52	85	86	75	75
query53	259	283	215	215
query54	281	242	220	220
query55	76	72	68	68
query56	299	295	284	284
query57	1449	1407	1337	1337
query58	281	241	258	241
query59	1614	1650	1420	1420
query60	306	270	249	249
query61	157	151	144	144
query62	694	654	573	573
query63	242	203	207	203
query64	2793	1072	874	874
query65	4841	4766	4771	4766
query66	1777	522	384	384
query67	29493	29423	29355	29355
query68	3230	1608	1029	1029
query69	415	301	278	278
query70	1080	969	940	940
query71	342	321	307	307
query72	2998	2683	2450	2450
query73	841	754	446	446
query74	5130	4974	4747	4747
query75	2628	2591	2209	2209
query76	2342	1186	793	793
query77	362	387	281	281
query78	12372	12388	11814	11814
query79	1423	1182	752	752
query80	1298	550	470	470
query81	524	327	276	276
query82	626	156	128	128
query83	369	332	298	298
query84	278	152	132	132
query85	951	609	515	515
query86	421	317	275	275
query87	1852	1830	1771	1771
query88	3724	2785	2757	2757
query89	448	421	366	366
query90	1902	201	194	194
query91	198	191	161	161
query92	66	64	57	57
query93	1664	1555	938	938
query94	719	362	328	328
query95	811	631	459	459
query96	1092	819	348	348
query97	2684	2699	2580	2580
query98	219	232	198	198
query99	1129	1171	1026	1026
Total cold run time: 266178 ms
Total hot run time: 180137 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.89 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit c35daaa4d41f08a9bdbe052ef3c4385f328088f1, data reload: false

query1	0.01	0.01	0.01
query2	0.10	0.05	0.05
query3	0.25	0.14	0.13
query4	1.60	0.13	0.14
query5	0.23	0.21	0.26
query6	1.21	1.09	1.07
query7	0.04	0.01	0.01
query8	0.05	0.04	0.03
query9	0.38	0.33	0.32
query10	0.55	0.54	0.52
query11	0.20	0.15	0.14
query12	0.20	0.14	0.14
query13	0.48	0.47	0.48
query14	1.01	1.01	1.01
query15	0.62	0.58	0.60
query16	0.31	0.34	0.31
query17	1.07	1.09	1.13
query18	0.22	0.21	0.20
query19	2.09	1.93	2.00
query20	0.02	0.01	0.01
query21	15.43	0.24	0.14
query22	4.82	0.05	0.05
query23	16.14	0.33	0.12
query24	2.96	0.42	0.34
query25	0.11	0.06	0.04
query26	0.73	0.20	0.16
query27	0.03	0.04	0.04
query28	3.53	0.92	0.50
query29	12.49	4.05	3.21
query30	0.29	0.15	0.16
query31	2.76	0.57	0.32
query32	3.21	0.58	0.49
query33	3.17	3.21	3.14
query34	15.57	4.29	3.50
query35	3.55	3.53	3.52
query36	0.56	0.44	0.43
query37	0.09	0.07	0.07
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.08	0.04	0.03
query42	0.04	0.03	0.03
query43	0.05	0.04	0.03
Total cold run time: 96.52 s
Total hot run time: 24.89 s

airborne12 added a commit to airborne12/apache-doris that referenced this pull request Jul 13, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#64909

Problem Summary: SNII inverted index files were finalized in begin_close(), but the underlying idx file writer was not closed until finish_close(). Load stream records segment file sizes between those phases, so it could observe an open .idx file and abort INSERT with "calc file size failed ... is not closed". Close the SNII idx writer asynchronously from begin_close(), leaving finish_close() to wait for completion. The previous local fix also restored only PeerCacheNodes after the file-cache profile trimming commit, but that trimming had removed the update path for still-declared segment_footer_index counters and peer cache CG/race/lazy counters. Restore those profile updates without reintroducing the removed redundant physical/block metrics, and extend the scanner profile unit test to cover all restored counters.

### Release note

None

### Check List (For Author)

- Test:
    - Build: ./build.sh --be
    - Manual test: deployed current output FE/BE after cleaning output runtime metadata; SHOW FRONTENDS and SHOW BACKENDS both Alive
    - Regression test: ./run-regression-test.sh --run -d inverted_index_p0/storage_format -s test_storage_format_snii
    - Unit Test: env LSAN_OPTIONS=exitcode=0 ./run-be-ut.sh --run --filter='IndexFileWriterTest.EmptySniiBeginCloseClosesUnderlyingWriter:FileScannerV2Test.FileCacheStatisticsArePublishedToScannerProfile'
    - Static check: git diff --check -- be/src/io/cache/block_file_cache_profile.cpp be/test/exec/scan/file_scanner_v2_test.cpp
    - Static check: PATH=/home/jiangkai/workspace/bin/ldb_toolchain/bin:$PATH build-support/check-format.sh
    - Static check: build-support/run-clang-tidy.sh --build-dir be/ut_build_ASAN attempted; local function-size warning removed, still blocked by toolchain stddef.h lookup and existing be/src/core/types.h unmatched NOLINTEND
- Behavior changed: No
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: apache#64909

Problem Summary: SNII inverted index files were finalized in begin_close(), but the underlying idx file writer was not closed until finish_close(). Load stream records segment file sizes between those phases, so it could observe an open .idx file and abort INSERT with "calc file size failed ... is not closed". Close the SNII idx writer asynchronously from begin_close(), leaving finish_close() to wait for completion. The previous local fix also restored only PeerCacheNodes after the file-cache profile trimming commit, but that trimming had removed the update path for still-declared segment_footer_index counters and peer cache CG/race/lazy counters. Restore those profile updates in FileCacheProfileReporter::update(), matching the existing profile update layout, without reintroducing the removed redundant physical/block metrics. Extend the scanner profile unit test to cover all restored counters.

### Release note

None

### Check List (For Author)

- Test:
    - Build: ./build.sh --be
    - Manual test: deployed current output FE/BE after cleaning output runtime metadata; SHOW FRONTENDS and SHOW BACKENDS both Alive
    - Regression test: ./run-regression-test.sh --run -d inverted_index_p0/storage_format -s test_storage_format_snii
    - Unit Test: env LSAN_OPTIONS=exitcode=0 ./run-be-ut.sh --run --filter='IndexFileWriterTest.EmptySniiBeginCloseClosesUnderlyingWriter:FileScannerV2Test.FileCacheStatisticsArePublishedToScannerProfile'
    - Static check: git diff --check -- be/src/io/cache/block_file_cache_profile.cpp
    - Static check: PATH=/home/jiangkai/workspace/bin/ldb_toolchain/bin:$PATH build-support/check-format.sh
    - Static check: build-support/run-clang-tidy.sh --build-dir be/ut_build_ASAN attempted; local function-size warnings are annotated, still blocked by toolchain stddef.h lookup
- Behavior changed: No
- Does this need documentation: No
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.39% (1896/2450)
Line Coverage 64.45% (34069/52862)
Region Coverage 64.87% (17536/27032)
Branch Coverage 54.03% (9395/17390)

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29758 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 0828706b134d58dc867db0e4e19bfba844622f9b, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17739	4108	4085	4085
q2	2008	337	205	205
q3	10294	1408	831	831
q4	4683	476	341	341
q5	7505	863	579	579
q6	191	200	140	140
q7	819	837	628	628
q8	9409	1520	1574	1520
q9	5672	4436	4423	4423
q10	6804	1784	1545	1545
q11	503	344	311	311
q12	757	552	421	421
q13	18127	3514	2760	2760
q14	266	256	249	249
q15	q16	782	769	712	712
q17	995	1017	982	982
q18	6910	5927	5591	5591
q19	1151	1192	1070	1070
q20	761	680	584	584
q21	5201	2670	2492	2492
q22	422	358	289	289
Total cold run time: 100999 ms
Total hot run time: 29758 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4342	4288	4261	4261
q2	280	318	209	209
q3	4599	4987	4482	4482
q4	2057	2166	1353	1353
q5	4442	4308	4322	4308
q6	231	177	129	129
q7	1704	1808	1861	1808
q8	2575	2195	2158	2158
q9	8008	8160	7761	7761
q10	4770	4712	4291	4291
q11	586	410	378	378
q12	758	770	560	560
q13	3191	3524	3051	3051
q14	317	301	278	278
q15	q16	745	735	636	636
q17	1332	1318	1319	1318
q18	8085	7705	7345	7345
q19	1137	1043	1044	1043
q20	2226	2185	1941	1941
q21	5226	4539	4401	4401
q22	534	450	426	426
Total cold run time: 57145 ms
Total hot run time: 52137 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 179863 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 0828706b134d58dc867db0e4e19bfba844622f9b, data reload: false

query5	4310	637	488	488
query6	461	229	196	196
query7	4912	616	347	347
query8	342	187	179	179
query9	8781	4157	4170	4157
query10	483	361	298	298
query11	5810	2374	2151	2151
query12	158	107	105	105
query13	1259	625	456	456
query14	6267	5322	4985	4985
query14_1	4302	4288	4298	4288
query15	230	206	184	184
query16	1016	487	455	455
query17	1144	746	568	568
query18	2460	465	339	339
query19	203	206	145	145
query20	107	106	103	103
query21	229	156	128	128
query22	13640	13678	13375	13375
query23	17462	16447	16238	16238
query23_1	16244	16284	16205	16205
query24	7587	1775	1301	1301
query24_1	1347	1318	1304	1304
query25	537	435	361	361
query26	1335	355	213	213
query27	2582	616	370	370
query28	4510	2027	2006	2006
query29	1072	614	481	481
query30	342	271	235	235
query31	1135	1090	975	975
query32	108	60	59	59
query33	522	319	244	244
query34	1161	1165	668	668
query35	793	773	666	666
query36	1377	1414	1184	1184
query37	160	105	94	94
query38	1878	1691	1662	1662
query39	928	926	898	898
query39_1	876	872	896	872
query40	242	155	144	144
query41	74	69	68	68
query42	97	95	103	95
query43	328	325	287	287
query44	1432	785	779	779
query45	202	194	188	188
query46	1063	1219	723	723
query47	2374	2309	2246	2246
query48	388	396	305	305
query49	600	433	350	350
query50	1072	433	327	327
query51	10822	10474	10546	10474
query52	89	90	83	83
query53	273	275	210	210
query54	292	251	249	249
query55	79	73	68	68
query56	305	308	306	306
query57	1433	1413	1326	1326
query58	298	281	270	270
query59	1573	1645	1410	1410
query60	314	275	265	265
query61	178	170	175	170
query62	695	647	595	595
query63	245	210	213	210
query64	2947	1130	839	839
query65	4910	4791	4762	4762
query66	1836	513	406	406
query67	29534	29395	29310	29310
query68	3264	1458	980	980
query69	405	299	261	261
query70	1092	982	974	974
query71	362	337	307	307
query72	3294	2706	2417	2417
query73	827	780	431	431
query74	5106	4944	4761	4761
query75	2608	2592	2232	2232
query76	2328	1182	756	756
query77	361	384	280	280
query78	12423	12261	11747	11747
query79	1446	1172	786	786
query80	1282	537	499	499
query81	554	319	276	276
query82	611	159	120	120
query83	359	317	293	293
query84	279	170	130	130
query85	943	577	514	514
query86	434	304	289	289
query87	1826	1820	1773	1773
query88	3696	2809	2818	2809
query89	464	395	351	351
query90	1935	202	197	197
query91	206	186	159	159
query92	64	62	58	58
query93	1756	1462	944	944
query94	734	359	320	320
query95	788	601	495	495
query96	1009	812	337	337
query97	2657	2717	2540	2540
query98	219	205	195	195
query99	1138	1190	1028	1028
Total cold run time: 266675 ms
Total hot run time: 179863 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 25.01 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 0828706b134d58dc867db0e4e19bfba844622f9b, data reload: false

query1	0.01	0.00	0.01
query2	0.10	0.04	0.05
query3	0.25	0.13	0.14
query4	1.61	0.14	0.14
query5	0.25	0.23	0.26
query6	1.27	1.05	1.06
query7	0.04	0.01	0.01
query8	0.06	0.04	0.05
query9	0.39	0.33	0.32
query10	0.55	0.55	0.54
query11	0.19	0.14	0.14
query12	0.18	0.15	0.14
query13	0.49	0.47	0.47
query14	1.02	1.01	1.01
query15	0.61	0.59	0.60
query16	0.31	0.35	0.33
query17	1.09	1.09	1.10
query18	0.23	0.22	0.21
query19	2.07	1.97	1.96
query20	0.01	0.01	0.01
query21	15.44	0.22	0.13
query22	4.91	0.04	0.05
query23	16.10	0.30	0.13
query24	2.94	0.43	0.32
query25	0.10	0.06	0.04
query26	0.73	0.21	0.14
query27	0.04	0.04	0.03
query28	3.50	0.90	0.53
query29	12.49	4.12	3.28
query30	0.27	0.15	0.16
query31	2.77	0.59	0.32
query32	3.22	0.59	0.48
query33	3.28	3.14	3.16
query34	15.62	4.24	3.54
query35	3.52	3.48	3.56
query36	0.58	0.44	0.43
query37	0.08	0.06	0.07
query38	0.05	0.04	0.04
query39	0.04	0.04	0.03
query40	0.18	0.17	0.16
query41	0.07	0.03	0.04
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.74 s
Total hot run time: 25.01 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 83.77% (9305/11108) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.70% (30419/41275)
Line Coverage 57.45% (330432/575177)
Region Coverage 54.06% (276263/511044)
Branch Coverage 54.82% (121858/222282)

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.

4 participants