Skip to content

feat: add segmented BTree index merge_segments support#6889

Merged
Xuanwo merged 3 commits into
lance-format:mainfrom
zhangyue19921010:btree-full-support-segment-final
Jun 5, 2026
Merged

feat: add segmented BTree index merge_segments support#6889
Xuanwo merged 3 commits into
lance-format:mainfrom
zhangyue19921010:btree-full-support-segment-final

Conversation

@zhangyue19921010

@zhangyue19921010 zhangyue19921010 commented May 21, 2026

Copy link
Copy Markdown
Contributor

Closes: #6979

Also refactored scalar index optimize logic in append.rs:

  1. Unified merge_scalar_indices — consolidates all scalar-index merge logic from merge_indices_with_unindexed_frags into one function with explicit segment selection and a single capability-based decision tree.

  2. Added BTreeIndex::merge_segments — a k-way segment merge primitive, enabling multi-segment consolidation without re-reading the dataset.

  3. num_indices_to_merge is now honored uniformly for all scalar types — previously scalar indices ignored it and always merged into one segment. Now append (=0) builds a delta only for the unindexed fragments, merge_N merges the latest N segments, and default/merge_1 merges the newest delta — matching the inverted/vector semantics.

  4. Multi-segment handling is capability-based, never a hard errormerge_scalar_indices picks per case:

    1. Append delta (no segment selected) → build a new segment over the unindexed fragments, keep the old ones.
    2. Supports N:1 merge (like BTree), ≥1 selected → k-way merge into one segment.
    3. No N:1 merge, exactly 1 selected → single-segment update().
    4. No N:1 merge, ≥2 selected → rebuild a fresh segment over the covered fragments (no k-way primitive, and lossy summary indexes can't re-emit rows).

Compatibility Testing

Context

Main branch ignores num_indices_to_merge for scalar indices — every mode merges the single old segment + new data → 1 segment. A multi-segment scalar index is a state that cannot exist on main.

Test Results (single-segment starting state — the only state main can produce)

Behavior is identical across all scalar types here (capability only matters once ≥2 segments exist):

Mode Main PR Diff
default / merge_1 / merge_2 1 seg (param ignored) 1 seg (merge newest + new) ✅ Same result
append 1 seg (param ignored) 2 seg (delta only) ⚠️ Changed

The only behavior change is append mode: it now produces a delta segment instead of silently merging. All other modes are unchanged from main.

PR-only new behavior: multi-segment scenarios (unreachable on main)

After accumulating N segments via repeated append-mode optimizes (applies to all scalar types):

Starting state Mode Result
3 segments + new data default / merge_1 3−1+1 = 3 segments (merge newest delta)
3 segments + new data merge_2 3−2+1 = 2 segments
3 segments + new data append 3+1 = 4 segments

For merge_2 (≥2 selected): types that support N:1 merge (like BTree) use the k-way merge primitive; types that don't consolidate via a full rebuild over the covered fragments. Both reach the same segment count.

Query correctness: All combinations verified — no data loss or incorrect results. Added tests for the delta-append, single-segment update, and multi-segment rebuild paths.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions github-actions Bot added the enhancement New feature or request label May 21, 2026
@codecov

codecov Bot commented May 21, 2026

Copy link
Copy Markdown

@github-actions github-actions Bot added the A-java Java bindings + JNI label May 21, 2026
@zhangyue19921010 zhangyue19921010 changed the title feat: add segmented BTree index planning and merge support feat: add segmented BTree index merge_segments support Jun 3, 2026
@zhangyue19921010
zhangyue19921010 force-pushed the btree-full-support-segment-final branch from ffc7cb8 to 9fce59f Compare June 3, 2026 14:56
@github-actions github-actions Bot added the A-index Vector index, linalg, tokenizer label Jun 3, 2026
@zhangyue19921010

Copy link
Copy Markdown
Contributor Author

Hi @Xuanwo This pr is ready for review. please take a look. thanks!

Resolve conflicts in index.rs and scalar.rs where main's segmented
Bitmap index work runs parallel to this branch's segmented BTree work:
- scalar.rs: register both `mod bitmap` and `mod btree`
- index.rs: keep both segment detectors and route merge_existing_index_segments
  to bitmap vs btree (vector / inverted / bitmap / btree)

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Comment thread rust/lance/src/index/append.rs Outdated
.num_indices_to_merge
.unwrap_or(1)
.min(old_indices.len()),
_ => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This makes a publicly reachable state fail during optimize. Multi-segment non-BTree scalar indexes can be committed today, but this guard rejects them instead of defining whether they should be unsupported at commit time or rebuilt during optimize.

@zhangyue19921010 zhangyue19921010 Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Nice Catch~

Removed the guard — optimize now handles multi-segment non-BTree gracefully instead of failing. merge_scalar_indices decides per case:

  1. Append delta (no segment selected) → build a new segment over the unindexed fragments, keep the old ones.
  2. Type supports N:1 merge, ≥1 selected → k-way merge into one segment.
  3. Type not supports N:1 merge, exactly 1 selected → single-segment update.
  4. Type not supports N:1 merge, ≥2 selected → rebuild a fresh segment over the covered fragments.

@zhangyue19921010

Copy link
Copy Markdown
Contributor Author

Hi @Xuanwo Thanks a lot for your help and review. Comments are all addressed. and CI passed. PTAL~

@Xuanwo Xuanwo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this!

@Xuanwo
Xuanwo merged commit c7ae55a into lance-format:main Jun 5, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-index Vector index, linalg, tokenizer A-java Java bindings + JNI enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add segmented BTree indexmerge support

2 participants