@@ -9,7 +9,7 @@ pub struct PrefixTrieBuilder<T> {
99 items : Vec < T > ,
1010}
1111
12- impl < T : Clone > PrefixTrieBuilder < T > {
12+ impl < T : Clone + Default > PrefixTrieBuilder < T > {
1313 pub fn new ( ) -> Self {
1414 PrefixTrieBuilder {
1515 children : HashMap :: new ( ) ,
@@ -37,14 +37,61 @@ impl<T: Clone> PrefixTrieBuilder<T> {
3737 total
3838 }
3939
40+ pub fn compute_children_in_order < A > (
41+ & self ,
42+ result : & mut Vec < A > ,
43+ c : & impl Fn ( & PrefixTrieBuilder < T > ) -> A ,
44+ mut cur_ix : usize ,
45+ ) {
46+ result[ cur_ix] = c ( self ) ;
47+ cur_ix += 1 ;
48+
49+ let mut ch = self
50+ . children
51+ . iter ( )
52+ . map ( |x| {
53+ let t = x. 1 . total_nodes ( ) ;
54+ ( x. 0 , x. 1 , t)
55+ } )
56+ . collect :: < Vec < _ > > ( ) ;
57+ ch. sort_by_key ( |x| ( x. 2 as isize ) . wrapping_neg ( ) ) ;
58+
59+ for ( _, child, _) in ch {
60+ let child_nodes = child. total_nodes ( ) ;
61+ child. compute_children_in_order ( result, c, cur_ix) ;
62+ cur_ix += child_nodes;
63+ }
64+ }
65+
4066 pub fn finalize ( self ) -> PrefixTrie < T > {
4167 let total_nodes = self . total_nodes ( ) ;
4268
69+ let mut num_children_in_order = vec ! [ 0 ; total_nodes] ;
70+ self . compute_children_in_order (
71+ & mut num_children_in_order,
72+ & |node : & PrefixTrieBuilder < T > | node. children . len ( ) ,
73+ 0 ,
74+ ) ;
75+
76+ let mut num_items_in_order = vec ! [ 0 ; total_nodes] ;
77+ self . compute_children_in_order (
78+ & mut num_items_in_order,
79+ & |node : & PrefixTrieBuilder < T > | node. items . len ( ) ,
80+ 0 ,
81+ ) ;
82+
83+ let mut lengths_in_order = vec ! [ 0 ; total_nodes] ;
84+ self . compute_children_in_order (
85+ & mut lengths_in_order,
86+ & |node : & PrefixTrieBuilder < T > | node. lengths . len ( ) ,
87+ 0 ,
88+ ) ;
89+
4390 let mut trie = PrefixTrie {
44- children : vec ! [ Vec :: new( ) ; total_nodes ] ,
91+ children : VecOfVec :: new ( num_children_in_order ) ,
4592 leafs : vec ! [ false ; total_nodes] ,
46- items : vec ! [ Vec :: new( ) ; total_nodes ] ,
47- ordered_lengths : vec ! [ vec! [ ] ; total_nodes ] ,
93+ items : VecOfVec :: new ( num_items_in_order ) ,
94+ ordered_lengths : VecOfVec :: new ( lengths_in_order ) ,
4895 characters : vec ! [ '\0' ; total_nodes] ,
4996 } ;
5097
@@ -54,13 +101,20 @@ impl<T: Clone> PrefixTrieBuilder<T> {
54101
55102 fn finalize_node ( self , trie : & mut PrefixTrie < T > , mut current_ix : IndexType ) {
56103 let my_ix = current_ix;
57- trie. ordered_lengths [ my_ix] = {
58- let mut lengths: Vec < usize > = self . lengths . into_iter ( ) . collect ( ) ;
59- lengths. sort_unstable ( ) ;
60- lengths. into_iter ( ) . map ( |x| x as LengthType ) . collect ( )
61- } ;
62- trie. items [ my_ix] = self . items ;
63- trie. leafs [ my_ix] = trie. ordered_lengths [ my_ix] . contains ( & 0 ) ;
104+
105+ let mut lengths: Vec < usize > = self . lengths . into_iter ( ) . collect ( ) ;
106+ lengths. sort_unstable ( ) ;
107+
108+ let length_ix = trie. ordered_lengths . indices [ my_ix] ;
109+ for ( i, l) in lengths. iter ( ) . enumerate ( ) {
110+ trie. ordered_lengths . data [ length_ix + i] = * l as LengthType ;
111+ }
112+
113+ let items_ix = trie. items . indices [ my_ix] ;
114+ for ( i, item) in self . items . into_iter ( ) . enumerate ( ) {
115+ trie. items . data [ items_ix + i] = item;
116+ }
117+ trie. leafs [ my_ix] = trie. ordered_lengths . ix ( my_ix) . any ( |x| * x == 0 ) ;
64118
65119 current_ix += 1 ;
66120
@@ -74,8 +128,9 @@ impl<T: Clone> PrefixTrieBuilder<T> {
74128 . collect :: < Vec < _ > > ( ) ;
75129 ch. sort_by_key ( |x| ( x. 2 as isize ) . wrapping_neg ( ) ) ;
76130
77- for ( c, child, _) in ch {
78- trie. children [ my_ix] . push ( current_ix) ;
131+ let child_ix = trie. children . indices [ my_ix] ;
132+ for ( i, ( c, child, _) ) in ch. into_iter ( ) . enumerate ( ) {
133+ trie. children . data [ child_ix + i] = current_ix;
79134 trie. characters [ current_ix] = c;
80135
81136 let child_nodes = child. total_nodes ( ) ;
@@ -85,36 +140,84 @@ impl<T: Clone> PrefixTrieBuilder<T> {
85140 }
86141}
87142
88- impl < T : Clone > Default for PrefixTrieBuilder < T > {
143+ impl < T : Clone + Default > Default for PrefixTrieBuilder < T > {
89144 fn default ( ) -> Self {
90145 PrefixTrieBuilder :: new ( )
91146 }
92147}
93148
149+ #[ derive( Clone ) ]
150+ struct VecOfVec < T > {
151+ data : Vec < T > ,
152+ indices : Vec < usize > ,
153+ }
154+
155+ fn cumsum ( lengths : Vec < usize > ) -> Vec < usize > {
156+ let mut indices = vec ! [ 0 ; lengths. len( ) + 1 ] ;
157+ let mut sum = 0 ;
158+ for ( i, length) in lengths. iter ( ) . enumerate ( ) {
159+ sum += * length;
160+ indices[ i + 1 ] = sum;
161+ }
162+ indices
163+ }
164+
165+ impl < T : Default + Clone > VecOfVec < T > {
166+ fn new ( lengths : Vec < usize > ) -> Self {
167+ VecOfVec {
168+ data : vec ! [ T :: default ( ) ; lengths. iter( ) . sum( ) ] ,
169+ indices : cumsum ( lengths) ,
170+ }
171+ }
172+
173+ fn ix ( & self , ix : usize ) -> VecOfVecIterator < ' _ , T > {
174+ VecOfVecIterator {
175+ vec_of_vec : self ,
176+ current_ix : self . indices [ ix] ,
177+ end_ix : self . indices [ ix + 1 ] ,
178+ }
179+ }
180+ }
181+
182+ struct VecOfVecIterator < ' a , T > {
183+ vec_of_vec : & ' a VecOfVec < T > ,
184+ current_ix : usize ,
185+ end_ix : usize ,
186+ }
187+
188+ impl < ' a , T > Iterator for VecOfVecIterator < ' a , T > {
189+ type Item = & ' a T ;
190+
191+ fn next ( & mut self ) -> Option < Self :: Item > {
192+ if self . current_ix < self . end_ix {
193+ let item = & self . vec_of_vec . data [ self . current_ix ] ;
194+ self . current_ix += 1 ;
195+ Some ( item)
196+ } else {
197+ None
198+ }
199+ }
200+ }
201+
94202type IndexType = usize ;
95203type LengthType = u16 ;
96204type DistanceType = u8 ;
97205type VisitedType = HashMap < ( IndexType , usize ) , DistanceType > ;
98206
99207#[ derive( Clone ) ]
100208pub struct PrefixTrie < T > {
101- children : Vec < Vec < IndexType > > ,
102- items : Vec < Vec < T > > ,
209+ children : VecOfVec < IndexType > ,
210+ items : VecOfVec < T > ,
103211 leafs : Vec < bool > ,
104212 characters : Vec < char > ,
105- ordered_lengths : Vec < Vec < LengthType > > ,
213+ ordered_lengths : VecOfVec < LengthType > ,
106214}
107215
108- impl < T > PrefixTrie < T > {
216+ impl < T : Clone + Default > PrefixTrie < T > {
109217 pub fn get_child ( & self , c : char , ix : IndexType ) -> Option < & IndexType > {
110- self . children [ ix] . iter ( ) . find_map ( |child_ix| {
111- let child_char = & self . characters [ * child_ix] ;
112- if * child_char == c {
113- Some ( child_ix)
114- } else {
115- None
116- }
117- } )
218+ self . children
219+ . ix ( ix)
220+ . find ( |child_ix| self . characters [ * * child_ix] == c)
118221 }
119222
120223 pub fn search ( & self , word : & str ) -> bool {
@@ -133,7 +236,7 @@ impl<T> PrefixTrie<T> {
133236 & ' a self ,
134237 prefix : & ' a str ,
135238 ix : IndexType ,
136- ) -> Box < dyn Iterator < Item = ( String , & T ) > + ' a > {
239+ ) -> Box < dyn Iterator < Item = ( String , & ' a T ) > + ' a > {
137240 let mut current_ix = ix;
138241 for c in prefix. chars ( ) {
139242 match self . get_child ( c, current_ix) {
@@ -143,8 +246,8 @@ impl<T> PrefixTrie<T> {
143246 }
144247
145248 Box :: new (
146- self . ordered_lengths [ current_ix ]
147- . iter ( )
249+ self . ordered_lengths
250+ . ix ( current_ix )
148251 . flat_map ( move |& x| self . childs_of_lengths ( current_ix, x) )
149252 . map ( move |( suffix, item) | {
150253 let mut full = String :: new ( ) ;
@@ -160,15 +263,15 @@ impl<T> PrefixTrie<T> {
160263 ix : IndexType ,
161264 length : LengthType ,
162265 ) -> Box < dyn Iterator < Item = ( String , & T ) > + ' _ > {
163- if !self . ordered_lengths [ ix ] . contains ( & length) {
266+ if !self . ordered_lengths . ix ( ix ) . any ( |x| * x == length) {
164267 return Box :: new ( std:: iter:: empty ( ) ) ;
165268 }
166269
167270 if length == 0 {
168- return Box :: new ( self . items [ ix ] . iter ( ) . map ( |item| ( String :: new ( ) , item) ) ) ;
271+ return Box :: new ( self . items . ix ( ix ) . map ( |item| ( String :: new ( ) , item) ) ) ;
169272 }
170273
171- Box :: new ( self . children [ ix ] . iter ( ) . flat_map ( move |child_ix| {
274+ Box :: new ( self . children . ix ( ix ) . flat_map ( move |child_ix| {
172275 let suffixes = self . childs_of_lengths ( * child_ix, length - 1 ) ;
173276 suffixes. map ( move |( suffix, item) | {
174277 let mut s = String :: new ( ) ;
@@ -223,7 +326,7 @@ pub struct PrefixTrieMaxDistanceIterator<'a, T> {
223326 word : Vec < char > ,
224327}
225328
226- impl < ' a , T > Iterator for PrefixTrieMaxDistanceIterator < ' a , T > {
329+ impl < ' a , T : Clone + Default > Iterator for PrefixTrieMaxDistanceIterator < ' a , T > {
227330 type Item = Box < dyn Iterator < Item = ( String , & ' a T ) > + ' a > ;
228331
229332 fn next ( & mut self ) -> Option < Self :: Item > {
@@ -261,7 +364,7 @@ pub struct PrefixTrieExactDistanceIterator<'a, T> {
261364 word : Vec < char > ,
262365}
263366
264- impl < ' a , T > Iterator for PrefixTrieExactDistanceIterator < ' a , T > {
367+ impl < ' a , T : Clone + Default > Iterator for PrefixTrieExactDistanceIterator < ' a , T > {
265368 type Item = Box < dyn Iterator < Item = ( String , & ' a T ) > + ' a > ;
266369
267370 fn next ( & mut self ) -> Option < Self :: Item > {
@@ -282,15 +385,11 @@ impl<'a, T> Iterator for PrefixTrieExactDistanceIterator<'a, T> {
282385 if distance == 0 && ( word_ix == self . word . len ( ) ) && self . trie . leafs [ node] {
283386 if self . continuations {
284387 to_return = Some ( Box :: new (
285- self . trie . items [ node]
286- . iter ( )
287- . map ( move |item| ( p. clone ( ) , item) ) ,
388+ self . trie . items . ix ( node) . map ( move |item| ( p. clone ( ) , item) ) ,
288389 ) ) ;
289390 } else {
290391 return Some ( Box :: new (
291- self . trie . items [ node]
292- . iter ( )
293- . map ( move |item| ( p. clone ( ) , item) ) ,
392+ self . trie . items . ix ( node) . map ( move |item| ( p. clone ( ) , item) ) ,
294393 ) ) ;
295394 }
296395 }
@@ -310,7 +409,7 @@ impl<'a, T> Iterator for PrefixTrieExactDistanceIterator<'a, T> {
310409 continue ;
311410 }
312411
313- for child in self . trie . children [ node ] . iter ( ) {
412+ for child in self . trie . children . ix ( node ) {
314413 // Substitution
315414 let character = self . trie . characters [ * child] ;
316415 if character != c {
@@ -327,7 +426,7 @@ impl<'a, T> Iterator for PrefixTrieExactDistanceIterator<'a, T> {
327426 . push ( ( node, word_ix + 1 , distance - 1 , prefix. clone ( ) ) ) ;
328427
329428 // Insertion
330- for child in self . trie . children [ node ] . iter ( ) {
429+ for child in self . trie . children . ix ( node ) {
331430 let character = self . trie . characters [ * child] ;
332431 if character != c {
333432 self . stack . push ( ( * child, word_ix, distance - 1 , {
@@ -350,7 +449,7 @@ impl<'a, T> Iterator for PrefixTrieExactDistanceIterator<'a, T> {
350449 if distance == 0 && !self . continuations {
351450 continue ;
352451 }
353- for child in self . trie . children [ node ] . iter ( ) {
452+ for child in self . trie . children . ix ( node ) {
354453 let character = self . trie . characters [ * child] ;
355454 self . stack . push ( (
356455 * child,
@@ -378,13 +477,13 @@ pub struct SearchIndex<TrieType> {
378477 trie : TrieType ,
379478}
380479
381- impl < T : Clone > Default for SearchIndex < PrefixTrieBuilder < T > > {
480+ impl < T : Clone + Default > Default for SearchIndex < PrefixTrieBuilder < T > > {
382481 fn default ( ) -> Self {
383482 SearchIndex :: new ( )
384483 }
385484}
386485
387- impl < T : Clone > SearchIndex < PrefixTrieBuilder < T > > {
486+ impl < T : Clone + Default > SearchIndex < PrefixTrieBuilder < T > > {
388487 pub fn new ( ) -> Self {
389488 SearchIndex {
390489 trie : PrefixTrieBuilder :: new ( ) ,
@@ -402,7 +501,7 @@ impl<T: Clone> SearchIndex<PrefixTrieBuilder<T>> {
402501 }
403502}
404503
405- impl < T : Clone > SearchIndex < PrefixTrie < T > > {
504+ impl < T : Clone + Default > SearchIndex < PrefixTrie < T > > {
406505 pub fn continuations < ' a > ( & ' a self , prefix : & ' a str ) -> Box < dyn Iterator < Item = & ' a T > + ' a > {
407506 Box :: new ( self . trie . continuations ( prefix, 0 ) . map ( |x| x. 1 ) )
408507 }
0 commit comments