Skip to content

Commit 2c967e5

Browse files
Malletscursoragent
andcommitted
refactor: share doc id mapping construction
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 2350c8e commit 2c967e5

2 files changed

Lines changed: 20 additions & 14 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ futures-util = { version = "0.3.28", optional = true }
7070
futures-channel = { version = "0.3.28", optional = true }
7171
fnv = "1.0.7"
7272
typetag = "0.2.21"
73+
unwrap-infallible = "1.0.0"
7374

7475
[target.'cfg(windows)'.dependencies]
7576
winapi = "0.3.9"

src/indexer/doc_id_mapping.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
//! This module is used when sorting the index by a property, e.g.
22
//! to get mappings from old doc_id to new doc_id and vice versa, after sorting
3+
use std::convert::Infallible;
4+
use std::error::Error;
5+
36
use common::{BitSet, ReadOnlyBitSet};
7+
use unwrap_infallible::UnwrapInfallible;
48

59
use super::SegmentWriter;
610
use crate::schema::{Field, Schema};
@@ -75,29 +79,29 @@ impl DocIdMapping {
7579
/// once in the mapping. I.e., doc ids must be consecutive from `0` to
7680
/// `new_doc_id_to_old.len() - 1`, inclusive.
7781
pub fn new_permutation(new_doc_id_to_old: Vec<DocId>) -> crate::Result<Self> {
78-
// Check that the mapping is a permutation of the segment doc ids.
7982
let max_doc = new_doc_id_to_old.len() as DocId;
80-
let mut old_doc_id_to_new = vec![0; max_doc as usize];
83+
let mut seen_doc_ids: BitSet = BitSet::with_max_value(max_doc);
8184

82-
let mut seen_doc_ids = BitSet::with_max_value(max_doc);
83-
for (i, old_doc_id) in new_doc_id_to_old.iter().copied().enumerate() {
85+
Self::from_new_id_to_old_id_inner(new_doc_id_to_old, |old_doc_id| {
8486
if old_doc_id >= max_doc || !seen_doc_ids.insert(old_doc_id) {
8587
return Err(TantivyError::InvalidArgument(
8688
"Mapping must be a permutation of the segment doc ids".to_string(),
8789
));
8890
}
89-
old_doc_id_to_new[new_doc_id_to_old[i] as usize] = i as DocId;
90-
}
91-
92-
let doc_id_mapping = DocIdMapping {
93-
new_doc_id_to_old,
94-
old_doc_id_to_new,
95-
};
96-
Ok(doc_id_mapping)
91+
Ok::<(), TantivyError>(())
92+
})
9793
}
9894

9995
/// Creates a `DocIdMapping` from a mapping of new doc ids to old doc ids.
10096
pub(crate) fn from_new_id_to_old_id(new_doc_id_to_old: Vec<DocId>) -> Self {
97+
Self::from_new_id_to_old_id_inner(new_doc_id_to_old, |_| Ok::<(), Infallible>(()))
98+
.unwrap_infallible()
99+
}
100+
101+
fn from_new_id_to_old_id_inner<E: Error>(
102+
new_doc_id_to_old: Vec<DocId>,
103+
mut check: impl FnMut(DocId) -> Result<(), E>,
104+
) -> Result<Self, E> {
101105
let max_doc = new_doc_id_to_old.len();
102106
let old_max_doc = new_doc_id_to_old
103107
.iter()
@@ -107,12 +111,13 @@ impl DocIdMapping {
107111
.unwrap_or(0);
108112
let mut old_doc_id_to_new = vec![0; old_max_doc as usize];
109113
for i in 0..max_doc {
114+
(check)(new_doc_id_to_old[i])?;
110115
old_doc_id_to_new[new_doc_id_to_old[i] as usize] = i as DocId;
111116
}
112-
DocIdMapping {
117+
Ok(DocIdMapping {
113118
new_doc_id_to_old,
114119
old_doc_id_to_new,
115-
}
120+
})
116121
}
117122

118123
/// Returns the new doc_id for the old doc_id

0 commit comments

Comments
 (0)