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+
36use common:: { BitSet , ReadOnlyBitSet } ;
7+ use unwrap_infallible:: UnwrapInfallible ;
48
59use super :: SegmentWriter ;
610use 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