Skip to content

perf(encoding): compact mini-block chunk index for cached page state#7651

Open
Ali2Arslan wants to merge 9 commits into
lance-format:mainfrom
Ali2Arslan:perf/miniblock-chunk-index
Open

perf(encoding): compact mini-block chunk index for cached page state#7651
Ali2Arslan wants to merge 9 commits into
lance-format:mainfrom
Ali2Arslan:perf/miniblock-chunk-index

Conversation

@Ali2Arslan

@Ali2Arslan Ali2Arslan commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

The mini-block structural scheduler caches per-page state that is consulted on
every read. Today that state is a Vec<ChunkMeta> (num_values, size, offset per
chunk) plus a repetition index of per-chunk blocks (first_row,
starts_including_trailer, has_preamble, has_trailer) — ~48 bytes/chunk, almost
all of it derivable from a handful of cumulative quantities.

This PR replaces both with a compact MiniBlockChunkIndex (new
primitive/chunk_index.rs submodule) that stores only the non-redundant data
and derives the rest:

  • byte_starts: PrefixSums — cumulative chunk byte sizes, stored as u32
    when the page's data buffer fits in 4 GiB and u64 otherwise.
  • rows: RowMapping selected by page shape:
    • UniformFlat — fixed-width / bitpacked pages where every non-last chunk
      holds the same number of values; row↔chunk is pure arithmetic with no
      heap allocation
      .
    • Flat — non-uniform flat pages (RLE / FSST); a single cumulative value
      array.
    • Nested — repetition present; cumulative row starts + a has_trailer
      bitmap (preamble derived from the previous chunk's trailer) + leaf item
      counts.

byte_range/items_in_chunk/find_chunk/first_row/rows_in_chunk/
has_preamble/has_trailer preserve the exact semantics the scheduler relied
on (find_chunk still returns the first of duplicated start rows). Row→chunk
lookups remain O(1) (uniform flat) or O(log n) (binary search), and the
multi-range instruction merge in schedule_instructions now runs in place
instead of allocating a second Vec.

MiniBlockChunkIndex implements DeepSizeOf (composing the inner
PrefixSums/ItemCounts/RowMapping), so cache weighing reflects the smaller
footprint.

This is an idiomatic port of an internal change to current upstream: it uses
lance's DeepSizeOf trait (rather than a bespoke size method), threads the
existing initialize IO structure, and drops fork-only test scaffolding that
has no counterpart here.

Test plan

  • cargo test -p lance-encoding --lib — 422 passed, 0 failed, 5 ignored
    (covers flat, non-uniform-flat, and nested/list miniblock round trips,
    e.g. test_sparse_large_string_list::...MINIBLOCK,
    test_sparse_boolean_list_uses_miniblock, test_nested_strings).
  • New unit tests: page-shape detection (test_flat_detection cases),
    nested row/item axes (test_nested_detection_and_axes), uniform-vs-Flat
    scheduler/lookup parity (test_uniform_flat_matches_prefix_sum_flat),
    per-variant heap-size bounds vs the legacy layout
    (test_deep_size_per_variant_below_legacy), and a parse_nested_rep
    oracle test against the previous per-block decode.
  • cargo fmt -p lance-encoding
  • cargo clippy -p lance-encoding --tests --benches -- -D warnings

Made with Cursor

The mini-block scheduler cached each page as a `Vec<ChunkMeta>` plus a
repetition index of per-chunk blocks (~48 bytes/chunk), most of which is
derivable from a few cumulative quantities.

Replace both with a compact `MiniBlockChunkIndex` that stores only the
non-redundant data and derives the rest: prefix-sum byte offsets (narrowed
to `u32` when the page fits) and a row mapping chosen per page shape --
`UniformFlat` (arithmetic, no allocation) for fixed-width/bitpacked pages,
`Flat` for non-uniform flat pages (RLE/FSST), and `Nested` (row prefix sums
+ a trailer bitmap) when a repetition index is present. Row->chunk lookups
stay O(1)/O(log n) and the scheduler's multi-range merge now runs in place.

The `DeepSizeOf` impl accounts for every retained buffer so cache weighing
reflects the smaller footprint. Adds unit tests for page-shape detection,
byte-range/row/item axes, uniform-vs-flat scheduler parity, and per-variant
size bounds.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added A-encoding Encoding, IO, file reader/writer performance labels Jul 7, 2026
Trim the docs and comments added in the previous commit to the project
convention: explain why not what, drop pure narration, and keep each to
2-3 lines. Comment/doc only; no behavior change.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.27626% with 14 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ing/src/encodings/logical/primitive/chunk_index.rs 96.04% 9 Missing and 2 partials ⚠️
.../lance-encoding/src/encodings/logical/primitive.rs 98.72% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

impl DeepSizeOf for MiniBlockCacheableState {
fn deep_size_of_children(&self, context: &mut Context) -> usize {
self.rep_index.deep_size_of_children(context)
self.chunk_index.deep_size_of_children(context)

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.

this also fixes the under-reporting (wasn't accounting for chunk_meta before)

// are _adjacent_ (i.e. don't merge "take first row of chunk 0" and "take third row of chunk 0" into "take 2
// rows of chunk 0 starting at 0")
if user_ranges.len() > 1 {
// TODO: Could probably optimize this allocation away

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.

bit of a drive-by, but addressed this as well

@westonpace
westonpace self-requested a review July 10, 2026 14:12

@westonpace westonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for looking at this. That schedule_instructions method still gives me nightmares. I'm glad we have LLMs now to deal with that kind of complexity.

The optimization is great, I think this is a good balance of performance and space. Do you have any benchmark results you can share?

Just a few nits around commenting. I'm mostly relying on the unit tests (the existing tests should be fairly complete) for correctness verification.

Comment on lines +6 to +9
//! Replaces two parallel per-chunk arrays (`Vec<ChunkMeta>` + a repetition index
//! of blocks, ~48 bytes/chunk) with the non-redundant cumulative quantities
//! alone, deriving the rest. The scheduler looks chunks up by index (byte range,
//! leaf value count) and by row (which chunk holds a row).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Minor nit: this comment will not age well as we have removed ChunkMeta so future readers won't know what this is talking about. Maybe:

The chunk index is stored on disk in an extremely compressed form that
requires a lot of CPU to work with.  However, extracting it out to its
full width can be RAM-intensive.  As a compromise we extract into a
prefix-sum array that we fit into u32 if possible and we avoid storing
per-block row counts when those are redundant.

Comment on lines +109 to +136
/// Index of the chunk whose half-open span `[get(i), get(i+1))` contains
/// `value`. On an exact hit against a chunk start, returns the *first* chunk
/// with that start (chunks can share a start row).
pub fn find(&self, value: u64) -> usize {
// Match the width once, then binary-search only the starts (not the
// trailing total). `partition_point` already yields the first of any
// duplicated starts; the `idx - 1` fallback is safe since `get(0) == 0`.
match self {
Self::U32(values) => {
let starts = &values[..values.len() - 1];
let idx = starts.partition_point(|&start| (start as u64) < value);
if idx < starts.len() && starts[idx] as u64 == value {
idx
} else {
idx - 1
}
}
Self::U64(values) => {
let starts = &values[..values.len() - 1];
let idx = starts.partition_point(|&start| start < value);
if idx < starts.len() && starts[idx] == value {
idx
} else {
idx - 1
}
}
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there any reason we can't use rust's builtin binary search function (https://doc.rust-lang.org/std/vec/struct.Vec.html#method.binary_search)?

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.

seems like Vec's binary search impl can return an arbitrary match (among equal entries), and we rely on the first of the duplicates semantic. The old code did use binary search but then walked back to find the first duplicate, I can do that instead, if you would like?

Comment on lines +139 to +146
impl DeepSizeOf for PrefixSums {
fn deep_size_of_children(&self, context: &mut Context) -> usize {
match self {
Self::U32(values) => values.deep_size_of_children(context),
Self::U64(values) => values.deep_size_of_children(context),
}
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Minor nit: you should be able to add the DeepSize derive and avoid this explicit impl

Comment on lines +157 to +158
/// `log2` of the value count of each chunk; the last chunk is handled via
/// `last_chunk_values`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe mention in the comment that we use log2 here for efficiency as this must be cached in RAM?

}
}

impl DeepSizeOf for ItemCounts {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, prefer derived DeepSize if possible

Comment on lines +246 to +247
/// Compact per-page chunk index that replaces the previous `Vec<ChunkMeta>`
/// plus repetition-index representation. See the module docs for the layout.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
/// Compact per-page chunk index that replaces the previous `Vec<ChunkMeta>`
/// plus repetition-index representation. See the module docs for the layout.
/// Compact per-page chunk index that avoids fully materializing the repetition
/// index into u64's to save RAM. See the module docs for the layout.

@Ali2Arslan

Copy link
Copy Markdown
Contributor Author

Thanks for looking at this. That schedule_instructions method still gives me nightmares. I'm glad we have LLMs now to deal with that kind of complexity.

The optimization is great, I think this is a good balance of performance and space. Do you have any benchmark results you can share?

Just a few nits around commenting. I'm mostly relying on the unit tests (the existing tests should be fairly complete) for correctness verification.

Thanks for taking a look Weston! I'll fix the comments!
re: benchmark results - for our specific use case:
Pre-PR: P50 = 27.1–30.3 KB, P90 = 528–595 KB, mean = 128 KB
Post-PR: P50 = 8.2 KB, P90 = 14.7 KB, mean = 95 KB
P90 pages for our use case were chunk-metadata dominated, so they saw a large reduction. We did not see much change in P99 sizes, those pages were likely dominated by the Option<Arc<DataBlock>> dict, I can introspect them, if you want.

Reword the module and struct docs to describe the CPU/RAM tradeoff instead
of the now-removed `ChunkMeta`, note that `ItemCounts::PerChunkLog` stores
log2 per chunk to stay compact in RAM, and replace the hand-written
`DeepSizeOf` impls for `PrefixSums` and `ItemCounts` with the derive.
No behavior change.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Pro Plus

Run ID: d758e087-a9fd-421e-a7ae-33207844cf33

📥 Commits

Reviewing files that changed from the base of the PR and between e7265e7 and e0973e4.

📒 Files selected for processing (1)
  • rust/lance-encoding/src/encodings/logical/primitive.rs

📝 Walkthrough

Walkthrough

MiniBlock structural decoding now builds compact MiniBlockChunkIndex representations for flat and nested layouts. Scheduler lookup, row-range instruction generation, preamble/trailer handling, cache state, and tests are updated to use the new index.

Changes

MiniBlock chunk indexing

Layer / File(s) Summary
Chunk index model and nested parsing
rust/lance-encoding/src/encodings/logical/primitive/chunk_index.rs
Adds compact prefix sums, item-count and row-mapping variants, MiniBlockChunkIndex accessors, nested repetition parsing, and focused unit tests.
Chunk index construction and cache initialization
rust/lance-encoding/src/encodings/logical/primitive.rs, rust/lance-encoding/src/encodings/logical/primitive/chunk_index.rs
Builds uniform-flat, non-uniform flat, or nested indexes from metadata and repetition bytes, then stores them in miniblock cache state.
Chunk lookup and instruction scheduling
rust/lance-encoding/src/encodings/logical/primitive.rs
Uses the new index for chunk lookup, row/take calculations, preamble and trailer decisions, in-place instruction merging, scheduling wiring, and updated regression tests.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested labels: enhancement

Suggested reviewers: westonpace

Sequence Diagram(s)

sequenceDiagram
  participant MiniBlockScheduler
  participant MiniBlockChunkIndex
  participant ChunkInstructions
  participant DataBuffer
  MiniBlockScheduler->>MiniBlockChunkIndex: lookup chunk byte ranges and item counts
  ChunkInstructions->>MiniBlockChunkIndex: locate chunks and row boundaries
  ChunkInstructions->>MiniBlockChunkIndex: read preamble and trailer flags
  ChunkInstructions->>DataBuffer: schedule merged chunk reads
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly reflects the main change: compacting the mini-block chunk index for cached page state.
Description check ✅ Passed The description matches the changeset and covers the new index design, lookup behavior, tests, and memory impact.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rust/lance-encoding/src/encodings/logical/primitive.rs`:
- Around line 1803-1806: Make build_chunk_index propagate Result and replace the
repetition-index length assert with Error::corrupt_file including the buffer
length and stride. In rust/lance-encoding/src/encodings/logical/primitive.rs
lines 1803-1806, update the rep_index_bytes path to return the checked error. In
rust/lance-encoding/src/encodings/logical/primitive/chunk_index.rs lines
393-431, make parse_nested_rep fallible, replace slice unwraps with error
handling, and validate cumulative subtraction so malformed bytes return
Error::corrupt_file instead of panicking.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c749cf27-70d9-4a63-9ecf-9a3672f24740

📥 Commits

Reviewing files that changed from the base of the PR and between 4754a76 and f7cb7d7.

📒 Files selected for processing (2)
  • rust/lance-encoding/src/encodings/logical/primitive.rs
  • rust/lance-encoding/src/encodings/logical/primitive/chunk_index.rs

Comment on lines +1803 to +1806
let rows = if let Some(rep_index_data) = rep_index_bytes {
assert!(rep_index_data.len() % 8 == 0);
let stride = repetition_index_depth as usize + 1;
let (row_starts, has_trailer) = parse_nested_rep(rep_index_data, stride);

@coderabbitai coderabbitai Bot Jul 20, 2026

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.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm build_chunk_index is only reached from a Result-returning context and locate the Error constructors available.
rg -nP '\bbuild_chunk_index\s*\(' rust/lance-encoding/src
rg -nP 'fn corrupt_file' rust/lance-core/src
rg -nP '\bparse_nested_rep\s*\(' rust/lance-encoding/src

Repository: lance-format/lance

Length of output: 2080


Return Error::corrupt_file for malformed repetition-index bytes

  • rust/lance-encoding/src/encodings/logical/primitive.rs#L1803-L1806: replace assert!(rep_index_data.len() % 8 == 0) with a checked error path and thread Result through build_chunk_index so the failure can include the buffer length and stride.
  • rust/lance-encoding/src/encodings/logical/primitive/chunk_index.rs#L393-L431: make parse_nested_rep fallible too; the slice .unwrap() and cumulative subtraction can panic on malformed bytes.
📍 Affects 2 files
  • rust/lance-encoding/src/encodings/logical/primitive.rs#L1803-L1806 (this comment)
  • rust/lance-encoding/src/encodings/logical/primitive/chunk_index.rs#L393-L431
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/lance-encoding/src/encodings/logical/primitive.rs` around lines 1803 -
1806, Make build_chunk_index propagate Result and replace the repetition-index
length assert with Error::corrupt_file including the buffer length and stride.
In rust/lance-encoding/src/encodings/logical/primitive.rs lines 1803-1806,
update the rep_index_bytes path to return the checked error. In
rust/lance-encoding/src/encodings/logical/primitive/chunk_index.rs lines
393-431, make parse_nested_rep fallible, replace slice unwraps with error
handling, and validate cumulative subtraction so malformed bytes return
Error::corrupt_file instead of panicking.

Source: Learnings

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.

I can do this, if we want @westonpace , though it's not technically related to this PR (it was like this before), but happy to fix it (either here - or as a separate follow-up)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A follow-up is fine

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.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rust/lance-encoding/src/encodings/logical/primitive.rs (1)

1733-1774: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Validate decoded chunk counts before subtracting.

items_in_page - counted is unchecked, while counted is derived from on-disk metadata. Corrupt metadata can therefore panic in debug builds or wrap in release builds, producing an invalid MiniBlockChunkIndex and potentially incorrect or out-of-bounds reads. The surrounding debug_assert! checks do not protect release builds.

Make the count-analysis helpers fallible, use checked arithmetic, return Error::corrupt_file with the chunk index and count values, propagate the error through build_chunk_index, and add malformed-metadata tests.

As per coding guidelines, validate inputs at API boundaries, use checked arithmetic, include full error context, and add tests for bug fixes.

Also applies to: 1884-1892

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/lance-encoding/src/encodings/logical/primitive.rs` around lines 1733 -
1774, Make analyze_value_counts and flat_value_counts_iter fallible, validating
each decoded chunk count before subtraction and using checked arithmetic for
shifts, accumulation, and remaining-count calculations. Return
Error::corrupt_file with the chunk index and relevant count values on invalid
metadata, then propagate the failure through build_chunk_index instead of
constructing an invalid MiniBlockChunkIndex. Add malformed-metadata tests
covering underflow and invalid decoded counts.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@rust/lance-encoding/src/encodings/logical/primitive.rs`:
- Around line 1733-1774: Make analyze_value_counts and flat_value_counts_iter
fallible, validating each decoded chunk count before subtraction and using
checked arithmetic for shifts, accumulation, and remaining-count calculations.
Return Error::corrupt_file with the chunk index and relevant count values on
invalid metadata, then propagate the failure through build_chunk_index instead
of constructing an invalid MiniBlockChunkIndex. Add malformed-metadata tests
covering underflow and invalid decoded counts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Pro Plus

Run ID: 714dcdbc-3ca5-408e-8d65-c8365a0eee7f

📥 Commits

Reviewing files that changed from the base of the PR and between f7cb7d7 and e61c57e.

📒 Files selected for processing (1)
  • rust/lance-encoding/src/encodings/logical/primitive.rs

@westonpace westonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like you addressed the review comments. Is this ready to merge?

Btw, in future PRs, if you hit re-request review then it will go back into my queue which makes it easier to keep track:

Image

@Ali2Arslan

Copy link
Copy Markdown
Contributor Author

Looks like you addressed the review comments. Is this ready to merge?

Btw, in future PRs, if you hit re-request review then it will go back into my queue which makes it easier to keep track:

Image

Yup ready to merge, and I see, will hit re-review in the future, thank you!!!!

@Ali2Arslan
Ali2Arslan requested a review from westonpace July 22, 2026 15:30

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rust/lance-encoding/src/encodings/logical/primitive.rs (1)

3327-3336: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Pass an owned DataType here SparseStructuralScheduler::try_new takes DataType, but target_field.data_type() yields &DataType; clone it at this call site.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/lance-encoding/src/encodings/logical/primitive.rs` around lines 3327 -
3336, Update the SparseLayout branch in the scheduler construction to pass an
owned DataType to SparseStructuralScheduler::try_new by cloning the value
returned from target_field.data_type(). Leave the surrounding arguments and
error propagation unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@rust/lance-encoding/src/encodings/logical/primitive.rs`:
- Around line 3327-3336: Update the SparseLayout branch in the scheduler
construction to pass an owned DataType to SparseStructuralScheduler::try_new by
cloning the value returned from target_field.data_type(). Leave the surrounding
arguments and error propagation unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Pro Plus

Run ID: 25a9ea19-e851-4e86-9cda-0ae3ecea8302

📥 Commits

Reviewing files that changed from the base of the PR and between e61c57e and c6b46bf.

📒 Files selected for processing (1)
  • rust/lance-encoding/src/encodings/logical/primitive.rs

Ali2Arslan and others added 2 commits July 22, 2026 08:46
The main merge pulled in the sparse structural encoding module
(primitive/sparse.rs), which still relies on the `ChunkMeta` struct this
branch had removed from the mini-block path. Re-add the struct so the new
consumer compiles; the mini-block scheduler continues to use the compact
`MiniBlockChunkIndex`.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-encoding Encoding, IO, file reader/writer performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants