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