1111//! Ordered containers with integer keys, implemented as radix tries (`TrieSet` and `TrieMap` types)
1212
1313use prelude:: * ;
14+ use mem;
1415use uint;
1516use util:: replace;
17+ use unstable:: intrinsics:: init;
1618use vec;
1719
1820// FIXME: #5244: need to manually update the TrieNode constructor
1921static SHIFT : uint = 4 ;
2022static SIZE : uint = 1 << SHIFT ;
2123static MASK : uint = SIZE - 1 ;
24+ static NUM_CHUNKS : uint = uint:: bits / SHIFT ;
2225
2326enum Child < T > {
2427 Internal ( ~TrieNode < T > ) ,
@@ -113,21 +116,25 @@ impl<T> TrieMap<T> {
113116
114117 /// Get an iterator over the key-value pairs in the map
115118 pub fn iter < ' a > ( & ' a self ) -> TrieMapIterator < ' a , T > {
116- TrieMapIterator {
117- stack : ~[ self . root . children . iter ( ) ] ,
118- remaining_min : self . length ,
119- remaining_max : self . length
120- }
119+ let mut iter = unsafe { TrieMapIterator :: new ( ) } ;
120+ iter. stack [ 0 ] = self . root . children . iter ( ) ;
121+ iter. length = 1 ;
122+ iter. remaining_min = self . length ;
123+ iter. remaining_max = self . length ;
124+
125+ iter
121126 }
122127
123128 /// Get an iterator over the key-value pairs in the map, with the
124129 /// ability to mutate the values.
125130 pub fn mut_iter < ' a > ( & ' a mut self ) -> TrieMapMutIterator < ' a , T > {
126- TrieMapMutIterator {
127- stack : ~[ self . root . children . mut_iter ( ) ] ,
128- remaining_min : self . length ,
129- remaining_max : self . length
130- }
131+ let mut iter = unsafe { TrieMapMutIterator :: new ( ) } ;
132+ iter. stack [ 0 ] = self . root . children . mut_iter ( ) ;
133+ iter. length = 1 ;
134+ iter. remaining_min = self . length ;
135+ iter. remaining_max = self . length ;
136+
137+ iter
131138 }
132139}
133140
@@ -176,16 +183,16 @@ macro_rules! bound {
176183
177184 let key = $key;
178185
179- let mut idx = 0 ;
180- let mut it = $iterator_name {
181- stack: ~[ ] ,
182- remaining_min: 0 ,
183- remaining_max: this. length
184- } ;
186+ let mut it = unsafe { $iterator_name:: new( ) } ;
187+ // everything else is zero'd, as we want.
188+ it. remaining_max = this. length;
189+
185190 // this addr is necessary for the `Internal` pattern.
186191 addr!( loop {
187192 let children = unsafe { addr!( & $( $mut_) * ( * node) . children) } ;
188- let child_id = chunk( key, idx) ;
193+ // it.length is the current depth in the iterator and the
194+ // current depth through the `uint` key we've traversed.
195+ let child_id = chunk( key, it. length) ;
189196 let ( slice_idx, ret) = match children[ child_id] {
190197 Internal ( ref $( $mut_) * n) => {
191198 node = addr!( & $( $mut_) * * * n as * $( $mut_) * TrieNode <T >) ;
@@ -202,9 +209,10 @@ macro_rules! bound {
202209 ( child_id + 1 , true )
203210 }
204211 } ;
205- it. stack. push( children. $slice_from( slice_idx) . $iter( ) ) ;
212+ // push to the stack.
213+ it. stack[ it. length] = children. $slice_from( slice_idx) . $iter( ) ;
214+ it. length += 1 ;
206215 if ret { return it }
207- idx += 1 ;
208216 } )
209217 }
210218 }
@@ -467,15 +475,17 @@ fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
467475
468476/// Forward iterator over a map
469477pub struct TrieMapIterator < ' a , T > {
470- priv stack : ~[ vec:: VecIterator < ' a , Child < T > > ] ,
478+ priv stack : [ vec:: VecIterator < ' a , Child < T > > , .. NUM_CHUNKS ] ,
479+ priv length : uint ,
471480 priv remaining_min : uint ,
472481 priv remaining_max : uint
473482}
474483
475484/// Forward iterator over the key-value pairs of a map, with the
476485/// values being mutable.
477486pub struct TrieMapMutIterator < ' a , T > {
478- priv stack : ~[ vec:: VecMutIterator < ' a , Child < T > > ] ,
487+ priv stack : [ vec:: VecMutIterator < ' a , Child < T > > , .. NUM_CHUNKS ] ,
488+ priv length : uint ,
479489 priv remaining_min : uint ,
480490 priv remaining_max : uint
481491}
@@ -487,27 +497,96 @@ macro_rules! iterator_impl {
487497 ( $name: ident,
488498 iter = $iter: ident,
489499 mutability = $( $mut_: tt) * ) => {
500+ impl <' a, T > $name<' a, T > {
501+ // Create new zero'd iterator. We have a thin gilding of safety by
502+ // using init rather than uninit, so that the worst that can happen
503+ // from failing to initialise correctly after calling these is a
504+ // segfault.
505+ #[ cfg( target_word_size="32" ) ]
506+ unsafe fn new( ) -> $name<' a, T > {
507+ $name {
508+ remaining_min: 0 ,
509+ remaining_max: 0 ,
510+ length: 0 ,
511+ // ick :( ... at least the compiler will tell us if we screwed up.
512+ stack: [ init( ) , init( ) , init( ) , init( ) , init( ) , init( ) , init( ) , init( ) ]
513+ }
514+ }
515+
516+ #[ cfg( target_word_size="64" ) ]
517+ unsafe fn new( ) -> $name<' a, T > {
518+ $name {
519+ remaining_min: 0 ,
520+ remaining_max: 0 ,
521+ length: 0 ,
522+ stack: [ init( ) , init( ) , init( ) , init( ) , init( ) , init( ) , init( ) , init( ) ,
523+ init( ) , init( ) , init( ) , init( ) , init( ) , init( ) , init( ) , init( ) ]
524+ }
525+ }
526+ }
527+
490528 item!( impl <' a, T > Iterator <( uint, & ' a $( $mut_) * T ) > for $name<' a, T > {
529+ // you might wonder why we're not even trying to act within the
530+ // rules, and are just manipulating raw pointers like there's no
531+ // such thing as invalid pointers and memory unsafety. The
532+ // reason is performance, without doing this we can get the
533+ // bench_iter_large microbenchmark down to about 30000 ns/iter
534+ // (using .unsafe_ref to index self.stack directly, 38000
535+ // ns/iter with [] checked indexing), but this smashes that down
536+ // to 13500 ns/iter.
537+ //
538+ // Fortunately, it's still safe...
539+ //
540+ // We have an invariant that every Internal node
541+ // corresponds to one push to self.stack, and one pop,
542+ // nested appropriately. self.stack has enough storage
543+ // to store the maximum depth of Internal nodes in the
544+ // trie (8 on 32-bit platforms, 16 on 64-bit).
491545 fn next( & mut self ) -> Option <( uint, & ' a $( $mut_) * T ) > {
492- while !self . stack. is_empty( ) {
493- match self . stack[ self . stack. len( ) - 1 ] . next( ) {
494- None => {
495- self . stack. pop( ) ;
496- }
497- Some ( child) => {
498- addr!( match * child {
499- Internal ( ref $( $mut_) * node) => {
500- self . stack. push( node. children. $iter( ) ) ;
501- }
502- External ( key, ref $( $mut_) * value) => {
503- self . remaining_max -= 1 ;
504- if self . remaining_min > 0 {
505- self . remaining_min -= 1 ;
546+ let start_ptr = self . stack. as_mut_ptr( ) ;
547+
548+ unsafe {
549+ // write_ptr is the next place to write to the stack.
550+ // invariant: start_ptr <= write_ptr < end of the
551+ // vector.
552+ let mut write_ptr = start_ptr. offset( self . length as int) ;
553+ while write_ptr != start_ptr {
554+ // indexing back one is safe, since write_ptr >
555+ // start_ptr now.
556+ match ( * write_ptr. offset( -1 ) ) . next( ) {
557+ // exhausted this iterator (i.e. finished this
558+ // Internal node), so pop from the stack.
559+ //
560+ // don't bother clearing the memory, because the
561+ // next time we use it we'll've written to it
562+ // first.
563+ None => write_ptr = write_ptr. offset( -1 ) ,
564+ Some ( child) => {
565+ addr!( match * child {
566+ Internal ( ref $( $mut_) * node) => {
567+ // going down a level, so push
568+ // to the stack (this is the
569+ // write referenced above)
570+ * write_ptr = node. children. $iter( ) ;
571+ write_ptr = write_ptr. offset( 1 ) ;
572+ }
573+ External ( key, ref $( $mut_) * value) => {
574+ self . remaining_max -= 1 ;
575+ if self . remaining_min > 0 {
576+ self . remaining_min -= 1 ;
577+ }
578+ // store the new length of the
579+ // stack, based on our current
580+ // position.
581+ self . length = ( write_ptr as uint
582+ - start_ptr as uint) /
583+ mem:: size_of_val( & * write_ptr) ;
584+
585+ return Some ( ( key, value) ) ;
506586 }
507- return Some ( ( key, value) ) ;
508- }
509- Nothing => { }
510- } )
587+ Nothing => { }
588+ } )
589+ }
511590 }
512591 }
513592 }
0 commit comments