@@ -51,6 +51,7 @@ pub mod linear {
51
51
FoundEntry ( uint ) , FoundHole ( uint ) , TableFull
52
52
}
53
53
54
+ #[ inline( always) ]
54
55
pure fn resize_at ( capacity : uint ) -> uint {
55
56
( ( capacity as float ) * 3. / 4. ) as uint
56
57
}
@@ -76,10 +77,8 @@ pub mod linear {
76
77
priv impl < K : Hash IterBytes Eq , V > LinearMap < K , V > {
77
78
#[ inline( always) ]
78
79
pure fn to_bucket ( & self , h : uint ) -> uint {
79
- // FIXME(#3041) borrow a more sophisticated technique here from
80
- // Gecko, for example borrowing from Knuth, as Eich so
81
- // colorfully argues for here:
82
- // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
80
+ // A good hash function with entropy spread over all of the
81
+ // bits is assumed. SipHash is more than good enough.
83
82
h % self . buckets . len ( )
84
83
}
85
84
@@ -128,12 +127,19 @@ pub mod linear {
128
127
TableFull
129
128
}
130
129
131
- /// Expands the capacity of the array and re-inserts each
132
- /// of the existing buckets.
130
+ /// Expand the capacity of the array to the next power of two
131
+ /// and re-insert each of the existing buckets.
132
+ #[ inline( always) ]
133
133
fn expand ( & mut self ) {
134
+ let new_capacity = self . buckets . len ( ) * 2 ;
135
+ self . resize ( new_capacity) ;
136
+ }
137
+
138
+ /// Expands the capacity of the array and re-insert each of the
139
+ /// existing buckets.
140
+ fn resize ( & mut self , new_capacity : uint ) {
134
141
let old_capacity = self . buckets . len ( ) ;
135
- let new_capacity = old_capacity * 2 ;
136
- self . resize_at = ( ( new_capacity as float ) * 3.0 / 4.0 ) as uint ;
142
+ self . resize_at = resize_at ( new_capacity) ;
137
143
138
144
let mut old_buckets = vec:: from_fn ( new_capacity, |_| None ) ;
139
145
self . buckets <-> old_buckets;
@@ -333,6 +339,14 @@ pub mod linear {
333
339
linear_map_with_capacity(INITIAL_CAPACITY)
334
340
}
335
341
342
+ /// Reserve space for at least `n` elements in the hash table.
343
+ fn reserve_at_least(&mut self, n: uint) {
344
+ if n > self.buckets.len() {
345
+ let buckets = n * 4 / 3 + 1;
346
+ self.resize(uint::next_power_of_two(buckets));
347
+ }
348
+ }
349
+
336
350
fn pop(&mut self, k: &K) -> Option<V> {
337
351
let hash = k.hash_keyed(self.k0, self.k1) as uint;
338
352
self.pop_internal(hash, k)
@@ -564,6 +578,11 @@ pub mod linear {
564
578
pub impl < T : Hash IterBytes Eq > LinearSet < T > {
565
579
/// Create an empty LinearSet
566
580
static fn new( ) -> LinearSet <T > { LinearSet { map: LinearMap :: new( ) } }
581
+
582
+ /// Reserve space for at least `n` elements in the hash table.
583
+ fn reserve_at_least ( & mut self , n : uint ) {
584
+ self . map . reserve_at_least ( n)
585
+ }
567
586
}
568
587
}
569
588
0 commit comments