Refactor and Split `rust/lance/src/index.rs` into submodules
Maintainers usually reply within 3 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 22/100
Research direction
Start from rust/lance/src/index.rs and the line ranges in the issue, then check how vector/hamming.rs and vector/details.rs reach private items through crate::index. Done means the split files compile, every existing path still resolves through re-exports, and the test-name list and attribute counts match before and after. Confirm this with cargo test -p lance --lib -- index:: and the diff of the test-name lists.
Written by the indexing model from the issue text.
Description
This is a pure move: code is relocated into submodules, no logic changes, 100% path compatibility through re-exports. The mechanics follow PR #9989 (dataset/blob.rs split). Line numbers below refer to the commit above.
1. Current module
Role. The crate::index facade.
Existing children and re-exports
- 12 children (81–92):
api,append,create,frag_reuse,frag_reuse_reader,frag_reuse_remapping,frag_reuse_with_stable_row_ids,mem_wal,prefilter,scalar,scalar_logical,vector. - Re-exports:
IndexParams,IndexBuildProgress,NoopIndexBuildProgress,DatasetIndexExt,IndexSegment,IntoIndexSegment,FilterLoader,PreFilter,LogicalIvfView,LogicalVectorIndex,CreateIndexBuilder,IndexDescription,pub(crate) vector_index_details*.
Concern groups (its own code)
- 118–151, 912–1187, 1505–1710 segment metadata validation/replay/type detection.
- 152–911 segment coverage & provenance:
remap_merged_segment_coverage,History,Snapshot,fresh_fragments,prune_stale_segment_coverage. - 1188–1504 prewarm.
- 1711–1874 cache keys.
- 1875–1922 misc.
- 1923–1930 unused
pub trait IndexBuilder. - 1931–2150 remap.
- 2151–2197
ScalarIndexInfo. - 2198–2211
open_index_proto. - 2212–2419
IndexDescriptionImpl. - 2420–3517
impl DatasetIndexExt for Dataset(1,100 lines). - 3518–3754 statistics.
- 3755–3932 listing/usability:
load_all_indices,index_is_usable,unsupported_index_version, …. - 3933–4043
pub trait DatasetIndexInternalExt. - 4044–4538 open paths
impl Dataset { *_with_purpose }(contains one 331-line fn). - 4539–5077
impl DatasetIndexInternalExt for Dataset. - 5078–5126 tail helpers.
Hidden coupling
- Descendants resolve private imports through the facade:
INDEX_FILE_NAMEfromcreate.rs,frag_reuse_remapping.rs,ivf/v2.rs;IndexTypefromvector/hamming.rs;IndexMetadatafromscalar.rs;pbfromvector.rs. vector/hamming.rs:41imports the private fnfilter_index_segments_by_ids.
Consumers
DatasetIndexExt/DatasetIndexInternalExtin ~100 files incl. python/java;load_all_indices~199 references.- From other modules:
index_is_usable,remap_index,build_index_metadata_from_segments,validate_segment_params_compatible,segment_has_vector_details,index_type_is_known,IvfIndexStateCacheKey,open_index_proto.
Tests
- One
mod tests: 143 fns;#[test]1,#[tokio::test142 (incl. one commented line at 8396),#[lance_test_macros::test(tokio::test)]1,#[rstest15,#[case56,#[values1; 4#[cfg(feature = "geo")]tests. - Shared fixtures: 5189–5280 and 5589–5775.
- Private items used:
aggregate_fts_prewarm_results,OpenedSegmentPrewarmResult,History,remap_deletes_all_indexed_rows,IndexDescriptionImpl::try_new,resolve_index_column,sources_at_build.
2. Split
Keep index.rs as the facade. New names do not collide with the 12 existing children.
| File | Contents (current lines) | ~lines |
|---|---|---|
index.rs (facade) |
1–117 (docs, imports incl. the ones descendants resolve, mod lines, existing pub use), 1711–1874 (cache keys; used by open paths and ivf/v2.rs tests), 1923–1930 (IndexBuilder), 2151–2197 (ScalarIndexInfo, private fields built in open.rs → fields become pub(super) or the literal site moves; choose pub(super) fields), 3930–4040 (DatasetIndexInternalExt trait incl. its doc block 3930–3932), new mod lines + re-exports |
~500 |
index/segments.rs |
118–151, 912–1187, 1505–1710 (segment validation, staged replay, build_index_metadata_from_segments, filter_index_segments_by_ids, validate_segment_*, segment_has_*_details, index_type_is_known) |
~760 |
index/segment_coverage.rs |
152–911 (remap_merged_segment_coverage, Snapshot, History, provenance, prune_stale_segment_coverage) + unit tests 5912–5991 (History) and 15367–15498 (sources_at_build) |
~980 |
index/prewarm.rs |
1188–1504 + unit tests 5281–5588 (use aggregate_fts_prewarm_results, OpenedSegmentPrewarmResult) |
~640 |
index/remap.rs |
1931–2150 + unit tests 8657–8887 | ~460 |
index/describe.rs |
2212–2419 (IndexDescriptionImpl, fragment_logical_rows_from_metadata) + unit tests 9232–9429, 11933–12019, 12088–12133 (use IndexDescriptionImpl::try_new) |
~560 |
index/statistics.rs |
1875–1922 (auto_migrate_corruption, type_name_from_uri, legacy_type_name), 3518–3754 |
~300 |
index/listing.rs |
3755–3929 (unsupported_index_version, index_is_usable, warn_about_unsupported_indices, load_all_indices, load_all_indices_by_name) |
~200 |
index/open.rs |
2198–2211 (open_index_proto), 4041–4052 (v0_frag_reuse_cache_id with its doc block 4041–4043), 4053–4538 (impl Dataset open paths), 4539–5077 (impl DatasetIndexInternalExt for Dataset), 5078–5115 (resolve_index_column) + unit tests 11508–11569, 12883–13035 |
~1,300 |
index/ext.rs |
2420–2459, 2460–3491 (impl DatasetIndexExt for Dataset), 3492–3517, 5116–5126 (is_vector_field) |
~1,120 |
index/test_util.rs (#[cfg(test)] pub(crate) mod test_util;) |
5189–5280, 5589–5775 (write_vector_segment_metadata, RequestIndexStoreWrapper, list_io_stats, segment_from_metadata, write_fragmented_vector_dataset, write_skewed_fragmented_vector_dataset, create_segmented_vector_index), all declared pub (see ground rule 9) |
~290 |
dataset/tests/dataset_index_segments.rs |
5776–6261 minus 5912–5991, 11570–12882 minus the two describe tests (merge/covering, staged btree row domains, commit_existing_index_segments; keep the #[cfg(feature = "geo")] attributes) |
~1,590 |
dataset/tests/dataset_index_training.rs |
6841–8363 (optimize delta, deferred training, partition caps) | ~1,530 |
dataset/tests/dataset_index_lifecycle.rs |
6262–6840, 8364–8656, 8888–9231, 9430–9992, 13902–14016, 15280–15366 | ~2,000 |
dataset/tests/dataset_index_nested.rs |
9993–11569 minus 11508–11569 (shallow clone, initialize_index, nested-field indices) |
~1,520 |
dataset/tests/dataset_index_files.rs |
13036–13901 (file sizes, describe totals, IOPS) | ~870 |
dataset/tests/dataset_index_unsupported.rs |
14017–15279 | ~1,270 |
Facade re-exports (same visibility as today): pub use open::DatasetIndexInternalExt is not needed because the trait stays in the facade; pub(crate) use segments::{replay_staged_segments, build_index_metadata_from_segments, validate_segment_params_compatible, segment_has_vector_details, index_type_is_known};, pub(crate) use remap::remap_index;, pub(crate) use listing::{unsupported_index_version, index_is_usable, warn_about_unsupported_indices, load_all_indices, load_all_indices_by_name};, private use segments::filter_index_segments_by_ids; and use open::open_index_proto; (descendants vector/hamming.rs, vector/details.rs resolve them through crate::index::). Register the six new test files in dataset/tests/mod.rs.
3. Cautions
- The items re-exported with
pub(crate) usemust be declaredpubin their child (lint);filter_index_segments_by_idsandopen_index_protobecomepub(super)(visible to all ofindex's descendants, which is exactly the current reach). - Private cross-file helpers to widen to
pub(super):validate_segment_metadata,remap_merged_segment_coverage,prune_stale_segment_coverage,validate_segment_index_details, the tensegment_has_*_details,prewarm_index_segments_by_metadata,IndexDescriptionImpl+try_new,find_frag_reuse_index_meta,index_statistics_{frag_reuse,mem_wal,scalar},resolve_index_column,mem_wal_catch_up_would_advance(ifext.rsand its caller separate; they do not: both stay inext.rs),load_index_with_purposeand the other*_with_purposemethods staypub(crate)methods (impl items are exempt). - Keep in the facade every import that descendants resolve through
crate::index::/super:::INDEX_FILE_NAME,IndexType,IndexMetadata,pb(see §1); do not "clean up" unused-looking imports there untilcargo check --all-targetspasses. - Moved bodies use bare child-module paths; add module-name imports instead of rewriting them:
segment_coverage.rsuse super::{append, frag_reuse};(170, 235);prewarm.rsuse super::scalar;(1274);remap.rsuse super::frag_reuse;(1981);statistics.rsuse super::scalar;(3680, 3685);ext.rsuse super::{append, frag_reuse, frag_reuse_reader, vector};(2700–3293);open.rsuse super::{frag_reuse, scalar, vector};(4063–5037). open_vector_index_from_metadata_with_planis a 331-line function: it moves whole.#[cfg(feature = "geo")]blocks at 2851, 2931, 2936 travel withext.rs; the four geo tests keep their attributes indataset_index_segments.rs.- Do not touch
dataset/tests/dataset_index.rs(already 7,849 lines). - Test invariant: 143 test fns; attribute counts as listed in §1 (note the commented
// #[tokio::test]at 8396 inflates a raw grep by one). - Delete
rust/lance/src/index.rsfromci/module_size_exceptions.txt. - Verify:
cargo test -p lance --lib -- index:: dataset::tests::dataset_index_; python/javacargo check(both importDatasetIndexExt,IndexSegment,NoopIndexBuildProgressvialance::index::).
4. Verification
Run before and after the move (all from the repo root):
# every new file < 3,000 lines and < 400 KB; CI replay against main
wc -lc <facade.rs> <facade>/*.rs <facade>/tests/*.rs
python3 ci/check_module_size.py main HEAD
# test invariant: attribute counts and the multiset of test fn names are unchanged
grep -hoE '#\[(test|tokio::test|rstest|case|values|serial_test::serial|test_log::test|lance_test_macros::test)' <old file | new files> | sort | uniq -c
cargo test -p <crate> --lib -- --list 2>/dev/null | grep ': test$' | sed 's/.*:://' | sort > names.{before,after}.txt && diff names.before.txt names.after.txt
# exactly what CI runs
cargo clippy --locked --features "$(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | .features | keys | .[]' | sort -u | paste -s -d ,)" --all-targets -- -D warnings
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps
cargo fmt --all -- --check
# module-specific commands: see the last bullet of section 3
(cd python && cargo check) # package pylance
(cd java/lance-jni && cargo check) # package lance-jni
Pure-move checklist for the PR description: no function body changed, no item renamed, no signature changed, visibility only widened where listed in section 3, every pre-existing path still resolves (re-exports), exceptions-list line removed (if listed), attribute counts and test names identical.
- Dominant language
- Rust
- Stars
- 7.2k
- Forks
- 900
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 366
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- Ships a Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from lance-format/lance
-
documentation
Difficulty 1/5 Under an hour Newbie friendliness 78/100
lance-format/lance#10225 ·
Maintainers usually reply within 3 days
-
feature performance
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
lance-format/lance#10137 ·
Maintainers usually reply within 3 days
-
After initialize_mem_wal, every FTS query logs "ERROR Index __lance_mem_wal has no fields"Possibly taken @lance-gatefixer claimed this 23 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
lance-format/lance#9655 ·
Maintainers usually reply within 3 days
-
Upgrade DataFusion for the unparser stack-overflow fixMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
lance-format/lance#8225 ·
Maintainers usually reply within 3 days
-
enhancement
Difficulty 1/5 Under an hour Newbie friendliness 84/100
lance-format/lance#6425 · 2 comments ·
Maintainers usually reply within 3 days
All issues in lance-format/lance
Similar issues
-
Small glitchOpenpriority: medium
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
storytold/photocraft#9538 ·
Maintainers usually reply within 1 day
-
bug P2 rust
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
jscott3201/rusty-bacnet#2085 ·
Maintainers usually reply within 1 day
-
area:tag area:tag---json---markdown--n bug factory:dogfood factory:triaged persona:scripter platform:linux-cloud priority:p3 type:bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
gitbutlerapp/grit#1940 · 1 comment ·
Maintainers usually reply within 1 day
-
Inconsistent case in names for Windows installation packages compared to all other assetsPossibly taken A pull request linked to this issue is open or already merged. Openarea:ui bug in progress needs-triage
Difficulty 1/5 Under an hour Newbie friendliness 65/100
bherbruck/solvecraft#6769 · 2 comments ·