]> git.lizzy.rs Git - rust.git/blob - src/libstd/collections/hash/table.rs
fd964cdf02c5363fe8c15b12b7694dd6cfd78539
[rust.git] / src / libstd / collections / hash / table.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 //
11 // ignore-lexer-test FIXME #15883
12
13 use clone::Clone;
14 use cmp;
15 use hash::{Hash, Hasher};
16 use iter::{Iterator, count};
17 use kinds::{Sized, marker};
18 use mem::{min_align_of, size_of};
19 use mem;
20 use num::{CheckedAdd, CheckedMul, is_power_of_two};
21 use ops::{Deref, DerefMut, Drop};
22 use option::{Some, None, Option};
23 use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory};
24 use ptr;
25 use rt::heap::{allocate, deallocate};
26
27 const EMPTY_BUCKET: u64 = 0u64;
28
29 /// The raw hashtable, providing safe-ish access to the unzipped and highly
30 /// optimized arrays of hashes, keys, and values.
31 ///
32 /// This design uses less memory and is a lot faster than the naive
33 /// `Vec<Option<u64, K, V>>`, because we don't pay for the overhead of an
34 /// option on every element, and we get a generally more cache-aware design.
35 ///
36 /// Essential invariants of this structure:
37 ///
38 ///   - if t.hashes[i] == EMPTY_BUCKET, then `Bucket::at_index(&t, i).raw`
39 ///     points to 'undefined' contents. Don't read from it. This invariant is
40 ///     enforced outside this module with the `EmptyBucket`, `FullBucket`,
41 ///     and `SafeHash` types.
42 ///
43 ///   - An `EmptyBucket` is only constructed at an index with
44 ///     a hash of EMPTY_BUCKET.
45 ///
46 ///   - A `FullBucket` is only constructed at an index with a
47 ///     non-EMPTY_BUCKET hash.
48 ///
49 ///   - A `SafeHash` is only constructed for non-`EMPTY_BUCKET` hash. We get
50 ///     around hashes of zero by changing them to 0x8000_0000_0000_0000,
51 ///     which will likely map to the same bucket, while not being confused
52 ///     with "empty".
53 ///
54 ///   - All three "arrays represented by pointers" are the same length:
55 ///     `capacity`. This is set at creation and never changes. The arrays
56 ///     are unzipped to save space (we don't have to pay for the padding
57 ///     between odd sized elements, such as in a map from u64 to u8), and
58 ///     be more cache aware (scanning through 8 hashes brings in at most
59 ///     2 cache lines, since they're all right beside each other).
60 ///
61 /// You can kind of think of this module/data structure as a safe wrapper
62 /// around just the "table" part of the hashtable. It enforces some
63 /// invariants at the type level and employs some performance trickery,
64 /// but in general is just a tricked out `Vec<Option<u64, K, V>>`.
65 #[unsafe_no_drop_flag]
66 pub struct RawTable<K, V> {
67     capacity: uint,
68     size:     uint,
69     hashes:   *mut u64,
70     // Because K/V do not appear directly in any of the types in the struct,
71     // inform rustc that in fact instances of K and V are reachable from here.
72     marker:   marker::CovariantType<(K,V)>,
73 }
74
75 struct RawBucket<K, V> {
76     hash: *mut u64,
77     key:  *mut K,
78     val:  *mut V
79 }
80
81 pub struct Bucket<K, V, M> {
82     raw:   RawBucket<K, V>,
83     idx:   uint,
84     table: M
85 }
86
87 pub struct EmptyBucket<K, V, M> {
88     raw:   RawBucket<K, V>,
89     idx:   uint,
90     table: M
91 }
92
93 pub struct FullBucket<K, V, M> {
94     raw:   RawBucket<K, V>,
95     idx:   uint,
96     table: M
97 }
98
99 pub type EmptyBucketImm<'table, K, V> = EmptyBucket<K, V, &'table RawTable<K, V>>;
100 pub type  FullBucketImm<'table, K, V> =  FullBucket<K, V, &'table RawTable<K, V>>;
101
102 pub type EmptyBucketMut<'table, K, V> = EmptyBucket<K, V, &'table mut RawTable<K, V>>;
103 pub type  FullBucketMut<'table, K, V> =  FullBucket<K, V, &'table mut RawTable<K, V>>;
104
105 pub enum BucketState<K, V, M> {
106     Empty(EmptyBucket<K, V, M>),
107     Full(FullBucket<K, V, M>),
108 }
109
110 // A GapThenFull encapsulates the state of two consecutive buckets at once.
111 // The first bucket, called the gap, is known to be empty.
112 // The second bucket is full.
113 struct GapThenFull<K, V, M> {
114     gap: EmptyBucket<K, V, ()>,
115     full: FullBucket<K, V, M>,
116 }
117
118 /// A hash that is not zero, since we use a hash of zero to represent empty
119 /// buckets.
120 #[deriving(PartialEq)]
121 pub struct SafeHash {
122     hash: u64,
123 }
124
125 impl SafeHash {
126     /// Peek at the hash value, which is guaranteed to be non-zero.
127     #[inline(always)]
128     pub fn inspect(&self) -> u64 { self.hash }
129 }
130
131 /// We need to remove hashes of 0. That's reserved for empty buckets.
132 /// This function wraps up `hash_keyed` to be the only way outside this
133 /// module to generate a SafeHash.
134 pub fn make_hash<Sized? T: Hash<S>, S, H: Hasher<S>>(hasher: &H, t: &T) -> SafeHash {
135     match hasher.hash(t) {
136         // This constant is exceedingly likely to hash to the same
137         // bucket, but it won't be counted as empty! Just so we can maintain
138         // our precious uniform distribution of initial indexes.
139         EMPTY_BUCKET => SafeHash { hash: 0x8000_0000_0000_0000 },
140         h            => SafeHash { hash: h },
141     }
142 }
143
144 // `replace` casts a `*u64` to a `*SafeHash`. Since we statically
145 // ensure that a `FullBucket` points to an index with a non-zero hash,
146 // and a `SafeHash` is just a `u64` with a different name, this is
147 // safe.
148 //
149 // This test ensures that a `SafeHash` really IS the same size as a
150 // `u64`. If you need to change the size of `SafeHash` (and
151 // consequently made this test fail), `replace` needs to be
152 // modified to no longer assume this.
153 #[test]
154 fn can_alias_safehash_as_u64() {
155     assert_eq!(size_of::<SafeHash>(), size_of::<u64>())
156 }
157
158 impl<K, V> RawBucket<K, V> {
159     unsafe fn offset(self, count: int) -> RawBucket<K, V> {
160         RawBucket {
161             hash: self.hash.offset(count),
162             key:  self.key.offset(count),
163             val:  self.val.offset(count),
164         }
165     }
166 }
167
168 // For parameterizing over mutability.
169
170 #[cfg(stage0)]
171 impl<'t, K, V> Deref<RawTable<K, V>> for &'t RawTable<K, V> {
172     fn deref(&self) -> &RawTable<K, V> {
173         &**self
174     }
175 }
176
177 #[cfg(stage0)]
178 impl<'t, K, V> Deref<RawTable<K, V>> for &'t mut RawTable<K, V> {
179     fn deref(&self) -> &RawTable<K,V> {
180         &**self
181     }
182 }
183
184 #[cfg(stage0)]
185 impl<'t, K, V> DerefMut<RawTable<K, V>> for &'t mut RawTable<K, V> {
186     fn deref_mut(&mut self) -> &mut RawTable<K,V> {
187         &mut **self
188     }
189 }
190
191 // Buckets hold references to the table.
192 impl<K, V, M> FullBucket<K, V, M> {
193     /// Borrow a reference to the table.
194     pub fn table(&self) -> &M {
195         &self.table
196     }
197     /// Move out the reference to the table.
198     pub fn into_table(self) -> M {
199         self.table
200     }
201     /// Get the raw index.
202     pub fn index(&self) -> uint {
203         self.idx
204     }
205 }
206
207 impl<K, V, M> EmptyBucket<K, V, M> {
208     /// Borrow a reference to the table.
209     pub fn table(&self) -> &M {
210         &self.table
211     }
212     /// Move out the reference to the table.
213     pub fn into_table(self) -> M {
214         self.table
215     }
216 }
217
218 impl<K, V, M> Bucket<K, V, M> {
219     /// Move out the reference to the table.
220     pub fn into_table(self) -> M {
221         self.table
222     }
223     /// Get the raw index.
224     pub fn index(&self) -> uint {
225         self.idx
226     }
227 }
228
229 impl<K, V, M: Deref<RawTable<K, V>>> Bucket<K, V, M> {
230     pub fn new(table: M, hash: &SafeHash) -> Bucket<K, V, M> {
231         Bucket::at_index(table, hash.inspect() as uint)
232     }
233
234     pub fn at_index(table: M, ib_index: uint) -> Bucket<K, V, M> {
235         let ib_index = ib_index & (table.capacity() - 1);
236         Bucket {
237             raw: unsafe {
238                table.first_bucket_raw().offset(ib_index as int)
239             },
240             idx: ib_index,
241             table: table
242         }
243     }
244
245     pub fn first(table: M) -> Bucket<K, V, M> {
246         Bucket {
247             raw: table.first_bucket_raw(),
248             idx: 0,
249             table: table
250         }
251     }
252
253     /// Reads a bucket at a given index, returning an enum indicating whether
254     /// it's initialized or not. You need to match on this enum to get
255     /// the appropriate types to call most of the other functions in
256     /// this module.
257     pub fn peek(self) -> BucketState<K, V, M> {
258         match unsafe { *self.raw.hash } {
259             EMPTY_BUCKET =>
260                 Empty(EmptyBucket {
261                     raw: self.raw,
262                     idx: self.idx,
263                     table: self.table
264                 }),
265             _ =>
266                 Full(FullBucket {
267                     raw: self.raw,
268                     idx: self.idx,
269                     table: self.table
270                 })
271         }
272     }
273
274     /// Modifies the bucket pointer in place to make it point to the next slot.
275     pub fn next(&mut self) {
276         // Branchless bucket iteration step.
277         // As we reach the end of the table...
278         // We take the current idx:          0111111b
279         // Xor it by its increment:        ^ 1000000b
280         //                               ------------
281         //                                   1111111b
282         // Then AND with the capacity:     & 1000000b
283         //                               ------------
284         // to get the backwards offset:      1000000b
285         // ... and it's zero at all other times.
286         let maybe_wraparound_dist = (self.idx ^ (self.idx + 1)) & self.table.capacity();
287         // Finally, we obtain the offset 1 or the offset -cap + 1.
288         let dist = 1i - (maybe_wraparound_dist as int);
289
290         self.idx += 1;
291
292         unsafe {
293             self.raw = self.raw.offset(dist);
294         }
295     }
296 }
297
298 impl<K, V, M: Deref<RawTable<K, V>>> EmptyBucket<K, V, M> {
299     #[inline]
300     pub fn next(self) -> Bucket<K, V, M> {
301         let mut bucket = self.into_bucket();
302         bucket.next();
303         bucket
304     }
305
306     #[inline]
307     pub fn into_bucket(self) -> Bucket<K, V, M> {
308         Bucket {
309             raw: self.raw,
310             idx: self.idx,
311             table: self.table
312         }
313     }
314
315     pub fn gap_peek(self) -> Option<GapThenFull<K, V, M>> {
316         let gap = EmptyBucket {
317             raw: self.raw,
318             idx: self.idx,
319             table: ()
320         };
321
322         match self.next().peek() {
323             Full(bucket) => {
324                 Some(GapThenFull {
325                     gap: gap,
326                     full: bucket
327                 })
328             }
329             Empty(..) => None
330         }
331     }
332 }
333
334 impl<K, V, M: DerefMut<RawTable<K, V>>> EmptyBucket<K, V, M> {
335     /// Puts given key and value pair, along with the key's hash,
336     /// into this bucket in the hashtable. Note how `self` is 'moved' into
337     /// this function, because this slot will no longer be empty when
338     /// we return! A `FullBucket` is returned for later use, pointing to
339     /// the newly-filled slot in the hashtable.
340     ///
341     /// Use `make_hash` to construct a `SafeHash` to pass to this function.
342     pub fn put(mut self, hash: SafeHash, key: K, value: V)
343                -> FullBucket<K, V, M> {
344         unsafe {
345             *self.raw.hash = hash.inspect();
346             ptr::write(self.raw.key, key);
347             ptr::write(self.raw.val, value);
348         }
349
350         self.table.size += 1;
351
352         FullBucket { raw: self.raw, idx: self.idx, table: self.table }
353     }
354 }
355
356 impl<K, V, M: Deref<RawTable<K, V>>> FullBucket<K, V, M> {
357     #[inline]
358     pub fn next(self) -> Bucket<K, V, M> {
359         let mut bucket = self.into_bucket();
360         bucket.next();
361         bucket
362     }
363
364     #[inline]
365     pub fn into_bucket(self) -> Bucket<K, V, M> {
366         Bucket {
367             raw: self.raw,
368             idx: self.idx,
369             table: self.table
370         }
371     }
372
373     /// Get the distance between this bucket and the 'ideal' location
374     /// as determined by the key's hash stored in it.
375     ///
376     /// In the cited blog posts above, this is called the "distance to
377     /// initial bucket", or DIB. Also known as "probe count".
378     pub fn distance(&self) -> uint {
379         // Calculates the distance one has to travel when going from
380         // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
381         // if the destination is not reached before the end of the table.
382         (self.idx - self.hash().inspect() as uint) & (self.table.capacity() - 1)
383     }
384
385     #[inline]
386     pub fn hash(&self) -> SafeHash {
387         unsafe {
388             SafeHash {
389                 hash: *self.raw.hash
390             }
391         }
392     }
393
394     /// Gets references to the key and value at a given index.
395     pub fn read(&self) -> (&K, &V) {
396         unsafe {
397             (&*self.raw.key,
398              &*self.raw.val)
399         }
400     }
401 }
402
403 impl<K, V, M: DerefMut<RawTable<K, V>>> FullBucket<K, V, M> {
404     /// Removes this bucket's key and value from the hashtable.
405     ///
406     /// This works similarly to `put`, building an `EmptyBucket` out of the
407     /// taken bucket.
408     pub fn take(mut self) -> (EmptyBucket<K, V, M>, K, V) {
409         let key = self.raw.key as *const K;
410         let val = self.raw.val as *const V;
411
412         self.table.size -= 1;
413
414         unsafe {
415             *self.raw.hash = EMPTY_BUCKET;
416             (
417                 EmptyBucket {
418                     raw: self.raw,
419                     idx: self.idx,
420                     table: self.table
421                 },
422                 ptr::read(key),
423                 ptr::read(val)
424             )
425         }
426     }
427
428     pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
429         unsafe {
430             let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
431             let old_key  = ptr::replace(self.raw.key,  k);
432             let old_val  = ptr::replace(self.raw.val,  v);
433
434             (old_hash, old_key, old_val)
435         }
436     }
437
438     /// Gets mutable references to the key and value at a given index.
439     pub fn read_mut(&mut self) -> (&mut K, &mut V) {
440         unsafe {
441             (&mut *self.raw.key,
442              &mut *self.raw.val)
443         }
444     }
445 }
446
447 impl<'t, K, V, M: Deref<RawTable<K, V>> + 't> FullBucket<K, V, M> {
448     /// Exchange a bucket state for immutable references into the table.
449     /// Because the underlying reference to the table is also consumed,
450     /// no further changes to the structure of the table are possible;
451     /// in exchange for this, the returned references have a longer lifetime
452     /// than the references returned by `read()`.
453     pub fn into_refs(self) -> (&'t K, &'t V) {
454         unsafe {
455             (&*self.raw.key,
456              &*self.raw.val)
457         }
458     }
459 }
460
461 impl<'t, K, V, M: DerefMut<RawTable<K, V>> + 't> FullBucket<K, V, M> {
462     /// This works similarly to `into_refs`, exchanging a bucket state
463     /// for mutable references into the table.
464     pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
465         unsafe {
466             (&mut *self.raw.key,
467              &mut *self.raw.val)
468         }
469     }
470 }
471
472 impl<K, V, M> BucketState<K, V, M> {
473     // For convenience.
474     pub fn expect_full(self) -> FullBucket<K, V, M> {
475         match self {
476             Full(full) => full,
477             Empty(..) => panic!("Expected full bucket")
478         }
479     }
480 }
481
482 impl<K, V, M: Deref<RawTable<K, V>>> GapThenFull<K, V, M> {
483     #[inline]
484     pub fn full(&self) -> &FullBucket<K, V, M> {
485         &self.full
486     }
487
488     pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
489         unsafe {
490             *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
491             copy_nonoverlapping_memory(self.gap.raw.key, self.full.raw.key as *const K, 1);
492             copy_nonoverlapping_memory(self.gap.raw.val, self.full.raw.val as *const V, 1);
493         }
494
495         let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
496
497         match self.full.next().peek() {
498             Full(bucket) => {
499                 self.gap.raw = prev_raw;
500                 self.gap.idx = prev_idx;
501
502                 self.full = bucket;
503
504                 Some(self)
505             }
506             Empty(..) => None
507         }
508     }
509 }
510
511
512 /// Rounds up to a multiple of a power of two. Returns the closest multiple
513 /// of `target_alignment` that is higher or equal to `unrounded`.
514 ///
515 /// # Failure
516 ///
517 /// Fails if `target_alignment` is not a power of two.
518 fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint {
519     assert!(is_power_of_two(target_alignment));
520     (unrounded + target_alignment - 1) & !(target_alignment - 1)
521 }
522
523 #[test]
524 fn test_rounding() {
525     assert_eq!(round_up_to_next(0, 4), 0);
526     assert_eq!(round_up_to_next(1, 4), 4);
527     assert_eq!(round_up_to_next(2, 4), 4);
528     assert_eq!(round_up_to_next(3, 4), 4);
529     assert_eq!(round_up_to_next(4, 4), 4);
530     assert_eq!(round_up_to_next(5, 4), 8);
531 }
532
533 // Returns a tuple of (key_offset, val_offset),
534 // from the start of a mallocated array.
535 fn calculate_offsets(hashes_size: uint,
536                      keys_size: uint, keys_align: uint,
537                      vals_align: uint)
538                      -> (uint, uint) {
539     let keys_offset = round_up_to_next(hashes_size, keys_align);
540     let end_of_keys = keys_offset + keys_size;
541
542     let vals_offset = round_up_to_next(end_of_keys, vals_align);
543
544     (keys_offset, vals_offset)
545 }
546
547 // Returns a tuple of (minimum required malloc alignment, hash_offset,
548 // array_size), from the start of a mallocated array.
549 fn calculate_allocation(hash_size: uint, hash_align: uint,
550                         keys_size: uint, keys_align: uint,
551                         vals_size: uint, vals_align: uint)
552                         -> (uint, uint, uint) {
553     let hash_offset = 0;
554     let (_, vals_offset) = calculate_offsets(hash_size,
555                                              keys_size, keys_align,
556                                                         vals_align);
557     let end_of_vals = vals_offset + vals_size;
558
559     let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
560
561     (min_align, hash_offset, end_of_vals)
562 }
563
564 #[test]
565 fn test_offset_calculation() {
566     assert_eq!(calculate_allocation(128, 8, 15, 1, 4,  4), (8, 0, 148));
567     assert_eq!(calculate_allocation(3,   1, 2,  1, 1,  1), (1, 0, 6));
568     assert_eq!(calculate_allocation(6,   2, 12, 4, 24, 8), (8, 0, 48));
569     assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144));
570     assert_eq!(calculate_offsets(3,   2,  1, 1), (3,   5));
571     assert_eq!(calculate_offsets(6,   12, 4, 8), (8,   24));
572 }
573
574 impl<K, V> RawTable<K, V> {
575     /// Does not initialize the buckets. The caller should ensure they,
576     /// at the very least, set every hash to EMPTY_BUCKET.
577     unsafe fn new_uninitialized(capacity: uint) -> RawTable<K, V> {
578         if capacity == 0 {
579             return RawTable {
580                 size: 0,
581                 capacity: 0,
582                 hashes: 0 as *mut u64,
583                 marker: marker::CovariantType,
584             };
585         }
586         // No need for `checked_mul` before a more restrictive check performed
587         // later in this method.
588         let hashes_size = capacity * size_of::<u64>();
589         let keys_size   = capacity * size_of::< K >();
590         let vals_size   = capacity * size_of::< V >();
591
592         // Allocating hashmaps is a little tricky. We need to allocate three
593         // arrays, but since we know their sizes and alignments up front,
594         // we just allocate a single array, and then have the subarrays
595         // point into it.
596         //
597         // This is great in theory, but in practice getting the alignment
598         // right is a little subtle. Therefore, calculating offsets has been
599         // factored out into a different function.
600         let (malloc_alignment, hash_offset, size) =
601             calculate_allocation(
602                 hashes_size, min_align_of::<u64>(),
603                 keys_size,   min_align_of::< K >(),
604                 vals_size,   min_align_of::< V >());
605
606         // One check for overflow that covers calculation and rounding of size.
607         let size_of_bucket = size_of::<u64>().checked_add(&size_of::<K>()).unwrap()
608                                              .checked_add(&size_of::<V>()).unwrap();
609         assert!(size >= capacity.checked_mul(&size_of_bucket)
610                                 .expect("capacity overflow"),
611                 "capacity overflow");
612
613         let buffer = allocate(size, malloc_alignment);
614         if buffer.is_null() { ::alloc::oom() }
615
616         let hashes = buffer.offset(hash_offset as int) as *mut u64;
617
618         RawTable {
619             capacity: capacity,
620             size:     0,
621             hashes:   hashes,
622             marker:   marker::CovariantType,
623         }
624     }
625
626     fn first_bucket_raw(&self) -> RawBucket<K, V> {
627         let hashes_size = self.capacity * size_of::<u64>();
628         let keys_size = self.capacity * size_of::<K>();
629
630         let buffer = self.hashes as *mut u8;
631         let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
632                                                            keys_size, min_align_of::<K>(),
633                                                            min_align_of::<V>());
634
635         unsafe {
636             RawBucket {
637                 hash: self.hashes,
638                 key:  buffer.offset(keys_offset as int) as *mut K,
639                 val:  buffer.offset(vals_offset as int) as *mut V
640             }
641         }
642     }
643
644     /// Creates a new raw table from a given capacity. All buckets are
645     /// initially empty.
646     #[allow(experimental)]
647     pub fn new(capacity: uint) -> RawTable<K, V> {
648         unsafe {
649             let ret = RawTable::new_uninitialized(capacity);
650             zero_memory(ret.hashes, capacity);
651             ret
652         }
653     }
654
655     /// The hashtable's capacity, similar to a vector's.
656     pub fn capacity(&self) -> uint {
657         self.capacity
658     }
659
660     /// The number of elements ever `put` in the hashtable, minus the number
661     /// of elements ever `take`n.
662     pub fn size(&self) -> uint {
663         self.size
664     }
665
666     fn raw_buckets(&self) -> RawBuckets<K, V> {
667         RawBuckets {
668             raw: self.first_bucket_raw(),
669             hashes_end: unsafe {
670                 self.hashes.offset(self.capacity as int)
671             },
672             marker: marker::ContravariantLifetime,
673         }
674     }
675
676     pub fn iter(&self) -> Entries<K, V> {
677         Entries {
678             iter: self.raw_buckets(),
679             elems_left: self.size(),
680         }
681     }
682
683     pub fn iter_mut(&mut self) -> MutEntries<K, V> {
684         MutEntries {
685             iter: self.raw_buckets(),
686             elems_left: self.size(),
687         }
688     }
689
690     pub fn into_iter(self) -> MoveEntries<K, V> {
691         let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
692         // Replace the marker regardless of lifetime bounds on parameters.
693         MoveEntries {
694             iter: RawBuckets {
695                 raw: raw,
696                 hashes_end: hashes_end,
697                 marker: marker::ContravariantLifetime,
698             },
699             table: self,
700         }
701     }
702
703     /// Returns an iterator that copies out each entry. Used while the table
704     /// is being dropped.
705     unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
706         let raw_bucket = self.first_bucket_raw();
707         RevMoveBuckets {
708             raw: raw_bucket.offset(self.capacity as int),
709             hashes_end: raw_bucket.hash,
710             elems_left: self.size,
711             marker:     marker::ContravariantLifetime,
712         }
713     }
714 }
715
716 /// A raw iterator. The basis for some other iterators in this module. Although
717 /// this interface is safe, it's not used outside this module.
718 struct RawBuckets<'a, K, V> {
719     raw: RawBucket<K, V>,
720     hashes_end: *mut u64,
721     marker: marker::ContravariantLifetime<'a>,
722 }
723
724 impl<'a, K, V> Iterator<RawBucket<K, V>> for RawBuckets<'a, K, V> {
725     fn next(&mut self) -> Option<RawBucket<K, V>> {
726         while self.raw.hash != self.hashes_end {
727             unsafe {
728                 // We are swapping out the pointer to a bucket and replacing
729                 // it with the pointer to the next one.
730                 let prev = ptr::replace(&mut self.raw, self.raw.offset(1));
731                 if *prev.hash != EMPTY_BUCKET {
732                     return Some(prev);
733                 }
734             }
735         }
736
737         None
738     }
739 }
740
741 /// An iterator that moves out buckets in reverse order. It leaves the table
742 /// in an an inconsistent state and should only be used for dropping
743 /// the table's remaining entries. It's used in the implementation of Drop.
744 struct RevMoveBuckets<'a, K, V> {
745     raw: RawBucket<K, V>,
746     hashes_end: *mut u64,
747     elems_left: uint,
748     marker: marker::ContravariantLifetime<'a>,
749 }
750
751 impl<'a, K, V> Iterator<(K, V)> for RevMoveBuckets<'a, K, V> {
752     fn next(&mut self) -> Option<(K, V)> {
753         if self.elems_left == 0 {
754             return None;
755         }
756
757         loop {
758             debug_assert!(self.raw.hash != self.hashes_end);
759
760             unsafe {
761                 self.raw = self.raw.offset(-1);
762
763                 if *self.raw.hash != EMPTY_BUCKET {
764                     self.elems_left -= 1;
765                     return Some((
766                         ptr::read(self.raw.key as *const K),
767                         ptr::read(self.raw.val as *const V)
768                     ));
769                 }
770             }
771         }
772     }
773 }
774
775 /// Iterator over shared references to entries in a table.
776 pub struct Entries<'a, K: 'a, V: 'a> {
777     iter: RawBuckets<'a, K, V>,
778     elems_left: uint,
779 }
780
781 /// Iterator over mutable references to entries in a table.
782 pub struct MutEntries<'a, K: 'a, V: 'a> {
783     iter: RawBuckets<'a, K, V>,
784     elems_left: uint,
785 }
786
787 /// Iterator over the entries in a table, consuming the table.
788 pub struct MoveEntries<K, V> {
789     table: RawTable<K, V>,
790     iter: RawBuckets<'static, K, V>
791 }
792
793 impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
794     fn next(&mut self) -> Option<(&'a K, &'a V)> {
795         self.iter.next().map(|bucket| {
796             self.elems_left -= 1;
797             unsafe {
798                 (&*bucket.key,
799                  &*bucket.val)
800             }
801         })
802     }
803
804     fn size_hint(&self) -> (uint, Option<uint>) {
805         (self.elems_left, Some(self.elems_left))
806     }
807 }
808
809 impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
810     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
811         self.iter.next().map(|bucket| {
812             self.elems_left -= 1;
813             unsafe {
814                 (&*bucket.key,
815                  &mut *bucket.val)
816             }
817         })
818     }
819
820     fn size_hint(&self) -> (uint, Option<uint>) {
821         (self.elems_left, Some(self.elems_left))
822     }
823 }
824
825 impl<K, V> Iterator<(SafeHash, K, V)> for MoveEntries<K, V> {
826     fn next(&mut self) -> Option<(SafeHash, K, V)> {
827         self.iter.next().map(|bucket| {
828             self.table.size -= 1;
829             unsafe {
830                 (
831                     SafeHash {
832                         hash: *bucket.hash,
833                     },
834                     ptr::read(bucket.key as *const K),
835                     ptr::read(bucket.val as *const V)
836                 )
837             }
838         })
839     }
840
841     fn size_hint(&self) -> (uint, Option<uint>) {
842         let size = self.table.size();
843         (size, Some(size))
844     }
845 }
846
847 impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
848     fn clone(&self) -> RawTable<K, V> {
849         unsafe {
850             let mut new_ht = RawTable::new_uninitialized(self.capacity());
851
852             {
853                 let cap = self.capacity();
854                 let mut new_buckets = Bucket::first(&mut new_ht);
855                 let mut buckets = Bucket::first(self);
856                 while buckets.index() != cap {
857                     match buckets.peek() {
858                         Full(full) => {
859                             let (h, k, v) = {
860                                 let (k, v) = full.read();
861                                 (full.hash(), k.clone(), v.clone())
862                             };
863                             *new_buckets.raw.hash = h.inspect();
864                             ptr::write(new_buckets.raw.key, k);
865                             ptr::write(new_buckets.raw.val, v);
866                         }
867                         Empty(..) => {
868                             *new_buckets.raw.hash = EMPTY_BUCKET;
869                         }
870                     }
871                     new_buckets.next();
872                     buckets.next();
873                 }
874             };
875
876             new_ht.size = self.size();
877
878             new_ht
879         }
880     }
881 }
882
883 #[unsafe_destructor]
884 impl<K, V> Drop for RawTable<K, V> {
885     fn drop(&mut self) {
886         if self.hashes.is_null() {
887             return;
888         }
889         // This is done in reverse because we've likely partially taken
890         // some elements out with `.into_iter()` from the front.
891         // Check if the size is 0, so we don't do a useless scan when
892         // dropping empty tables such as on resize.
893         // Also avoid double drop of elements that have been already moved out.
894         unsafe {
895             for _ in self.rev_move_buckets() {}
896         }
897
898         let hashes_size = self.capacity * size_of::<u64>();
899         let keys_size = self.capacity * size_of::<K>();
900         let vals_size = self.capacity * size_of::<V>();
901         let (align, _, size) = calculate_allocation(hashes_size, min_align_of::<u64>(),
902                                                     keys_size, min_align_of::<K>(),
903                                                     vals_size, min_align_of::<V>());
904
905         unsafe {
906             deallocate(self.hashes as *mut u8, size, align);
907             // Remember how everything was allocated out of one buffer
908             // during initialization? We only need one call to free here.
909         }
910     }
911 }