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.
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.
11 use alloc::heap::{EMPTY, allocate, deallocate};
14 use hash::{BuildHasher, Hash, Hasher};
15 use intrinsics::needs_drop;
17 use mem::{align_of, size_of};
19 use ops::{Deref, DerefMut};
20 use ptr::{self, Unique, Shared};
22 use self::BucketState::*;
24 /// Integer type used for stored hash values.
26 /// No more than bit_width(usize) bits are needed to select a bucket.
28 /// The most significant bit is ours to use for tagging `SafeHash`.
30 /// (Even if we could have usize::MAX bytes allocated for buckets,
31 /// each bucket stores at least a `HashUint`, so there can be no more than
32 /// usize::MAX / size_of(usize) buckets.)
33 type HashUint = usize;
35 const EMPTY_BUCKET: HashUint = 0;
37 /// Special `Unique<HashUint>` that uses the lower bit of the pointer
38 /// to expose a boolean tag.
39 /// Note: when the pointer is initialized to EMPTY `.ptr()` will return
40 /// null and the tag functions shouldn't be used.
41 struct TaggedHashUintPtr(Unique<HashUint>);
43 impl TaggedHashUintPtr {
45 unsafe fn new(ptr: *mut HashUint) -> Self {
46 debug_assert!(ptr as usize & 1 == 0 || ptr as usize == EMPTY as usize);
47 TaggedHashUintPtr(Unique::new(ptr))
51 fn set_tag(&mut self, value: bool) {
52 let usize_ptr = &*self.0 as *const *mut HashUint as *mut usize;
63 fn tag(&self) -> bool {
64 (*self.0 as usize) & 1 == 1
68 fn ptr(&self) -> *mut HashUint {
69 (*self.0 as usize & !1) as *mut HashUint
73 /// The raw hashtable, providing safe-ish access to the unzipped and highly
74 /// optimized arrays of hashes, and key-value pairs.
76 /// This design is a lot faster than the naive
77 /// `Vec<Option<(u64, K, V)>>`, because we don't pay for the overhead of an
78 /// option on every element, and we get a generally more cache-aware design.
80 /// Essential invariants of this structure:
82 /// - if t.hashes[i] == EMPTY_BUCKET, then `Bucket::at_index(&t, i).raw`
83 /// points to 'undefined' contents. Don't read from it. This invariant is
84 /// enforced outside this module with the `EmptyBucket`, `FullBucket`,
85 /// and `SafeHash` types.
87 /// - An `EmptyBucket` is only constructed at an index with
88 /// a hash of EMPTY_BUCKET.
90 /// - A `FullBucket` is only constructed at an index with a
91 /// non-EMPTY_BUCKET hash.
93 /// - A `SafeHash` is only constructed for non-`EMPTY_BUCKET` hash. We get
94 /// around hashes of zero by changing them to 0x8000_0000_0000_0000,
95 /// which will likely map to the same bucket, while not being confused
98 /// - Both "arrays represented by pointers" are the same length:
99 /// `capacity`. This is set at creation and never changes. The arrays
100 /// are unzipped and are more cache aware (scanning through 8 hashes
101 /// brings in at most 2 cache lines, since they're all right beside each
102 /// other). This layout may waste space in padding such as in a map from
103 /// u64 to u8, but is a more cache conscious layout as the key-value pairs
104 /// are only very shortly probed and the desired value will be in the same
105 /// or next cache line.
107 /// You can kind of think of this module/data structure as a safe wrapper
108 /// around just the "table" part of the hashtable. It enforces some
109 /// invariants at the type level and employs some performance trickery,
110 /// but in general is just a tricked out `Vec<Option<(u64, K, V)>>`.
112 /// The hashtable also exposes a special boolean tag. The tag defaults to false
113 /// when the RawTable is created and is accessible with the `tag` and `set_tag`
115 pub struct RawTable<K, V> {
118 hashes: TaggedHashUintPtr,
120 // Because K/V do not appear directly in any of the types in the struct,
121 // inform rustc that in fact instances of K and V are reachable from here.
122 marker: marker::PhantomData<(K, V)>,
125 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
126 unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
128 pub struct RawBucket<K, V> {
130 // We use *const to ensure covariance with respect to K and V
132 _marker: marker::PhantomData<(K, V)>,
135 impl<K, V> Copy for RawBucket<K, V> {}
136 impl<K, V> Clone for RawBucket<K, V> {
137 fn clone(&self) -> RawBucket<K, V> {
142 pub struct Bucket<K, V, M> {
143 raw: RawBucket<K, V>,
148 impl<K, V, M: Copy> Copy for Bucket<K, V, M> {}
149 impl<K, V, M: Copy> Clone for Bucket<K, V, M> {
150 fn clone(&self) -> Bucket<K, V, M> {
155 pub struct EmptyBucket<K, V, M> {
156 raw: RawBucket<K, V>,
161 pub struct FullBucket<K, V, M> {
162 raw: RawBucket<K, V>,
167 pub type FullBucketMut<'table, K, V> = FullBucket<K, V, &'table mut RawTable<K, V>>;
169 pub enum BucketState<K, V, M> {
170 Empty(EmptyBucket<K, V, M>),
171 Full(FullBucket<K, V, M>),
174 // A GapThenFull encapsulates the state of two consecutive buckets at once.
175 // The first bucket, called the gap, is known to be empty.
176 // The second bucket is full.
177 pub struct GapThenFull<K, V, M> {
178 gap: EmptyBucket<K, V, ()>,
179 full: FullBucket<K, V, M>,
182 /// A hash that is not zero, since we use a hash of zero to represent empty
184 #[derive(PartialEq, Copy, Clone)]
185 pub struct SafeHash {
190 /// Peek at the hash value, which is guaranteed to be non-zero.
192 pub fn inspect(&self) -> HashUint {
197 pub fn new(hash: u64) -> Self {
198 // We need to avoid 0 in order to prevent collisions with
199 // EMPTY_HASH. We can maintain our precious uniform distribution
200 // of initial indexes by unconditionally setting the MSB,
201 // effectively reducing the hashes by one bit.
203 // Truncate hash to fit in `HashUint`.
204 let hash_bits = size_of::<HashUint>() * 8;
205 SafeHash { hash: (1 << (hash_bits - 1)) | (hash as HashUint) }
209 /// We need to remove hashes of 0. That's reserved for empty buckets.
210 /// This function wraps up `hash_keyed` to be the only way outside this
211 /// module to generate a SafeHash.
212 pub fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> SafeHash
216 let mut state = hash_state.build_hasher();
218 SafeHash::new(state.finish())
221 // `replace` casts a `*HashUint` to a `*SafeHash`. Since we statically
222 // ensure that a `FullBucket` points to an index with a non-zero hash,
223 // and a `SafeHash` is just a `HashUint` with a different name, this is
226 // This test ensures that a `SafeHash` really IS the same size as a
227 // `HashUint`. If you need to change the size of `SafeHash` (and
228 // consequently made this test fail), `replace` needs to be
229 // modified to no longer assume this.
231 fn can_alias_safehash_as_hash() {
232 assert_eq!(size_of::<SafeHash>(), size_of::<HashUint>())
235 impl<K, V> RawBucket<K, V> {
236 unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
238 hash: self.hash.offset(count),
239 pair: self.pair.offset(count),
240 _marker: marker::PhantomData,
245 // Buckets hold references to the table.
246 impl<K, V, M> FullBucket<K, V, M> {
247 /// Borrow a reference to the table.
248 pub fn table(&self) -> &M {
251 /// Borrow a mutable reference to the table.
252 pub fn table_mut(&mut self) -> &mut M {
255 /// Move out the reference to the table.
256 pub fn into_table(self) -> M {
259 /// Get the raw index.
260 pub fn index(&self) -> usize {
263 /// Get the raw bucket.
264 pub fn raw(&self) -> RawBucket<K, V> {
269 impl<K, V, M> EmptyBucket<K, V, M> {
270 /// Borrow a reference to the table.
271 pub fn table(&self) -> &M {
274 /// Borrow a mutable reference to the table.
275 pub fn table_mut(&mut self) -> &mut M {
280 impl<K, V, M> Bucket<K, V, M> {
281 /// Get the raw index.
282 pub fn index(&self) -> usize {
286 pub fn into_table(self) -> M {
291 impl<K, V, M> Deref for FullBucket<K, V, M>
292 where M: Deref<Target = RawTable<K, V>>
294 type Target = RawTable<K, V>;
295 fn deref(&self) -> &RawTable<K, V> {
300 /// `Put` is implemented for types which provide access to a table and cannot be invalidated
301 /// by filling a bucket. A similar implementation for `Take` is possible.
302 pub trait Put<K, V> {
303 unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V>;
307 impl<'t, K, V> Put<K, V> for &'t mut RawTable<K, V> {
308 unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
313 impl<K, V, M> Put<K, V> for Bucket<K, V, M>
316 unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
317 self.table.borrow_table_mut()
321 impl<K, V, M> Put<K, V> for FullBucket<K, V, M>
324 unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
325 self.table.borrow_table_mut()
329 impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
330 pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
331 Bucket::at_index(table, hash.inspect() as usize)
334 pub fn new_from(r: RawBucket<K, V>, i: usize, t: M)
344 pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
345 // if capacity is 0, then the RawBucket will be populated with bogus pointers.
346 // This is an uncommon case though, so avoid it in release builds.
347 debug_assert!(table.capacity() > 0,
348 "Table should have capacity at this point");
349 let ib_index = ib_index & (table.capacity() - 1);
351 raw: unsafe { table.first_bucket_raw().offset(ib_index as isize) },
357 pub fn first(table: M) -> Bucket<K, V, M> {
359 raw: table.first_bucket_raw(),
365 // "So a few of the first shall be last: for many be called,
368 // We'll most likely encounter a few buckets at the beginning that
369 // have their initial buckets near the end of the table. They were
370 // placed at the beginning as the probe wrapped around the table
371 // during insertion. We must skip forward to a bucket that won't
372 // get reinserted too early and won't unfairly steal others spot.
373 // This eliminates the need for robin hood.
374 pub fn head_bucket(table: M) -> Bucket<K, V, M> {
375 let mut bucket = Bucket::first(table);
378 bucket = match bucket.peek() {
380 if full.displacement() == 0 {
381 // This bucket occupies its ideal spot.
382 // It indicates the start of another "cluster".
383 bucket = full.into_bucket();
386 // Leaving this bucket in the last cluster for later.
390 // Encountered a hole between clusters.
399 /// Reads a bucket at a given index, returning an enum indicating whether
400 /// it's initialized or not. You need to match on this enum to get
401 /// the appropriate types to call most of the other functions in
403 pub fn peek(self) -> BucketState<K, V, M> {
404 match unsafe { *self.raw.hash } {
422 /// Modifies the bucket pointer in place to make it point to the next slot.
423 pub fn next(&mut self) {
425 let range = self.table.capacity();
426 // This code is branchless thanks to a conditional move.
427 let dist = if self.idx & (range - 1) == 0 {
433 self.raw = self.raw.offset(dist);
437 /// Modifies the bucket pointer in place to make it point to the previous slot.
438 pub fn prev(&mut self) {
439 let range = self.table.capacity();
440 let new_idx = self.idx.wrapping_sub(1) & (range - 1);
441 let dist = (new_idx as isize).wrapping_sub(self.idx as isize);
444 self.raw = self.raw.offset(dist);
449 impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
451 pub fn next(self) -> Bucket<K, V, M> {
452 let mut bucket = self.into_bucket();
458 pub fn into_bucket(self) -> Bucket<K, V, M> {
466 pub fn gap_peek(self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
467 let gap = EmptyBucket {
473 match self.next().peek() {
480 Empty(e) => Err(e.into_bucket()),
485 impl<K, V, M> EmptyBucket<K, V, M>
488 /// Puts given key and value pair, along with the key's hash,
489 /// into this bucket in the hashtable. Note how `self` is 'moved' into
490 /// this function, because this slot will no longer be empty when
491 /// we return! A `FullBucket` is returned for later use, pointing to
492 /// the newly-filled slot in the hashtable.
494 /// Use `make_hash` to construct a `SafeHash` to pass to this function.
495 pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
497 *self.raw.hash = hash.inspect();
498 ptr::write(self.raw.pair as *mut (K, V), (key, value));
500 self.table.borrow_table_mut().size += 1;
510 /// Puts given key, remain value uninitialized.
511 /// It is only used for inplacement insertion.
512 pub unsafe fn put_key(mut self, hash: SafeHash, key: K) -> FullBucket<K, V, M> {
513 *self.raw.hash = hash.inspect();
514 let pair_mut = self.raw.pair as *mut (K, V);
515 ptr::write(&mut (*pair_mut).0, key);
517 self.table.borrow_table_mut().size += 1;
527 impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
529 pub fn next(self) -> Bucket<K, V, M> {
530 let mut bucket = self.into_bucket();
536 pub fn into_bucket(self) -> Bucket<K, V, M> {
544 /// Duplicates the current position. This can be useful for operations
545 /// on two or more buckets.
546 pub fn stash(self) -> FullBucket<K, V, Self> {
554 /// Get the distance between this bucket and the 'ideal' location
555 /// as determined by the key's hash stored in it.
557 /// In the cited blog posts above, this is called the "distance to
558 /// initial bucket", or DIB. Also known as "probe count".
559 pub fn displacement(&self) -> usize {
560 // Calculates the distance one has to travel when going from
561 // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
562 // if the destination is not reached before the end of the table.
563 (self.idx.wrapping_sub(self.hash().inspect() as usize)) & (self.table.capacity() - 1)
567 pub fn hash(&self) -> SafeHash {
568 unsafe { SafeHash { hash: *self.raw.hash } }
571 /// Gets references to the key and value at a given index.
572 pub fn read(&self) -> (&K, &V) {
573 unsafe { (&(*self.raw.pair).0, &(*self.raw.pair).1) }
577 // We take a mutable reference to the table instead of accepting anything that
578 // implements `DerefMut` to prevent fn `take` from being called on `stash`ed
580 impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
581 /// Removes this bucket's key and value from the hashtable.
583 /// This works similarly to `put`, building an `EmptyBucket` out of the
585 pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
586 self.table.size -= 1;
589 *self.raw.hash = EMPTY_BUCKET;
590 let (k, v) = ptr::read(self.raw.pair);
601 /// Remove this bucket's `key` from the hashtable.
602 /// Only used for inplacement insertion.
603 /// NOTE: `Value` is uninitialized when this function is called, don't try to drop the `Value`.
604 pub unsafe fn remove_key(&mut self) {
605 self.table.size -= 1;
607 *self.raw.hash = EMPTY_BUCKET;
608 let pair_mut = self.raw.pair as *mut (K, V);
609 ptr::drop_in_place(&mut (*pair_mut).0); // only drop key
613 // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases
614 // where `M` is a full bucket or table reference type with mutable access to the table.
615 impl<K, V, M> FullBucket<K, V, M>
618 pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
620 let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
621 let (old_key, old_val) = ptr::replace(self.raw.pair as *mut (K, V), (k, v));
623 (old_hash, old_key, old_val)
628 impl<K, V, M> FullBucket<K, V, M>
629 where M: Deref<Target = RawTable<K, V>> + DerefMut
631 /// Gets mutable references to the key and value at a given index.
632 pub fn read_mut(&mut self) -> (&mut K, &mut V) {
633 let pair_mut = self.raw.pair as *mut (K, V);
634 unsafe { (&mut (*pair_mut).0, &mut (*pair_mut).1) }
638 impl<'t, K, V, M> FullBucket<K, V, M>
639 where M: Deref<Target = RawTable<K, V>> + 't
641 /// Exchange a bucket state for immutable references into the table.
642 /// Because the underlying reference to the table is also consumed,
643 /// no further changes to the structure of the table are possible;
644 /// in exchange for this, the returned references have a longer lifetime
645 /// than the references returned by `read()`.
646 pub fn into_refs(self) -> (&'t K, &'t V) {
647 unsafe { (&(*self.raw.pair).0, &(*self.raw.pair).1) }
651 impl<'t, K, V, M> FullBucket<K, V, M>
652 where M: Deref<Target = RawTable<K, V>> + DerefMut + 't
654 /// This works similarly to `into_refs`, exchanging a bucket state
655 /// for mutable references into the table.
656 pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
657 let pair_mut = self.raw.pair as *mut (K, V);
658 unsafe { (&mut (*pair_mut).0, &mut (*pair_mut).1) }
662 impl<K, V, M> GapThenFull<K, V, M>
663 where M: Deref<Target = RawTable<K, V>>
666 pub fn full(&self) -> &FullBucket<K, V, M> {
670 pub fn into_bucket(self) -> Bucket<K, V, M> {
671 self.full.into_bucket()
674 pub fn shift(mut self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
676 *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
677 ptr::copy_nonoverlapping(self.full.raw.pair, self.gap.raw.pair as *mut (K, V), 1);
680 let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
682 match self.full.next().peek() {
684 self.gap.raw = prev_raw;
685 self.gap.idx = prev_idx;
691 Empty(b) => Err(b.into_bucket()),
697 /// Rounds up to a multiple of a power of two. Returns the closest multiple
698 /// of `target_alignment` that is higher or equal to `unrounded`.
702 /// Panics if `target_alignment` is not a power of two.
704 fn round_up_to_next(unrounded: usize, target_alignment: usize) -> usize {
705 assert!(target_alignment.is_power_of_two());
706 (unrounded + target_alignment - 1) & !(target_alignment - 1)
711 assert_eq!(round_up_to_next(0, 4), 0);
712 assert_eq!(round_up_to_next(1, 4), 4);
713 assert_eq!(round_up_to_next(2, 4), 4);
714 assert_eq!(round_up_to_next(3, 4), 4);
715 assert_eq!(round_up_to_next(4, 4), 4);
716 assert_eq!(round_up_to_next(5, 4), 8);
719 // Returns a tuple of (pairs_offset, end_of_pairs_offset),
720 // from the start of a mallocated array.
722 fn calculate_offsets(hashes_size: usize,
725 -> (usize, usize, bool) {
726 let pairs_offset = round_up_to_next(hashes_size, pairs_align);
727 let (end_of_pairs, oflo) = pairs_offset.overflowing_add(pairs_size);
729 (pairs_offset, end_of_pairs, oflo)
732 // Returns a tuple of (minimum required malloc alignment, hash_offset,
733 // array_size), from the start of a mallocated array.
734 fn calculate_allocation(hash_size: usize,
738 -> (usize, usize, usize, bool) {
740 let (_, end_of_pairs, oflo) = calculate_offsets(hash_size, pairs_size, pairs_align);
742 let align = cmp::max(hash_align, pairs_align);
744 (align, hash_offset, end_of_pairs, oflo)
748 fn test_offset_calculation() {
749 assert_eq!(calculate_allocation(128, 8, 16, 8), (8, 0, 144, false));
750 assert_eq!(calculate_allocation(3, 1, 2, 1), (1, 0, 5, false));
751 assert_eq!(calculate_allocation(6, 2, 12, 4), (4, 0, 20, false));
752 assert_eq!(calculate_offsets(128, 15, 4), (128, 143, false));
753 assert_eq!(calculate_offsets(3, 2, 4), (4, 6, false));
754 assert_eq!(calculate_offsets(6, 12, 4), (8, 20, false));
757 impl<K, V> RawTable<K, V> {
758 /// Does not initialize the buckets. The caller should ensure they,
759 /// at the very least, set every hash to EMPTY_BUCKET.
760 unsafe fn new_uninitialized(capacity: usize) -> RawTable<K, V> {
765 hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint),
766 marker: marker::PhantomData,
770 // No need for `checked_mul` before a more restrictive check performed
771 // later in this method.
772 let hashes_size = capacity.wrapping_mul(size_of::<HashUint>());
773 let pairs_size = capacity.wrapping_mul(size_of::<(K, V)>());
775 // Allocating hashmaps is a little tricky. We need to allocate two
776 // arrays, but since we know their sizes and alignments up front,
777 // we just allocate a single array, and then have the subarrays
780 // This is great in theory, but in practice getting the alignment
781 // right is a little subtle. Therefore, calculating offsets has been
782 // factored out into a different function.
783 let (alignment, hash_offset, size, oflo) = calculate_allocation(hashes_size,
784 align_of::<HashUint>(),
786 align_of::<(K, V)>());
787 assert!(!oflo, "capacity overflow");
789 // One check for overflow that covers calculation and rounding of size.
790 let size_of_bucket = size_of::<HashUint>().checked_add(size_of::<(K, V)>()).unwrap();
792 capacity.checked_mul(size_of_bucket)
793 .expect("capacity overflow"),
794 "capacity overflow");
796 let buffer = allocate(size, alignment);
797 if buffer.is_null() {
801 let hashes = buffer.offset(hash_offset as isize) as *mut HashUint;
806 hashes: TaggedHashUintPtr::new(hashes),
807 marker: marker::PhantomData,
811 fn first_bucket_raw(&self) -> RawBucket<K, V> {
812 let hashes_size = self.capacity * size_of::<HashUint>();
813 let pairs_size = self.capacity * size_of::<(K, V)>();
815 let buffer = self.hashes.ptr() as *mut u8;
816 let (pairs_offset, _, oflo) =
817 calculate_offsets(hashes_size, pairs_size, align_of::<(K, V)>());
818 debug_assert!(!oflo, "capacity overflow");
821 hash: self.hashes.ptr(),
822 pair: buffer.offset(pairs_offset as isize) as *const _,
823 _marker: marker::PhantomData,
828 /// Creates a new raw table from a given capacity. All buckets are
830 pub fn new(capacity: usize) -> RawTable<K, V> {
832 let ret = RawTable::new_uninitialized(capacity);
833 ptr::write_bytes(ret.hashes.ptr(), 0, capacity);
838 /// The hashtable's capacity, similar to a vector's.
839 pub fn capacity(&self) -> usize {
843 /// The number of elements ever `put` in the hashtable, minus the number
844 /// of elements ever `take`n.
845 pub fn size(&self) -> usize {
849 fn raw_buckets(&self) -> RawBuckets<K, V> {
851 raw: self.first_bucket_raw(),
852 hashes_end: unsafe { self.hashes.ptr().offset(self.capacity as isize) },
853 marker: marker::PhantomData,
857 pub fn iter(&self) -> Iter<K, V> {
859 iter: self.raw_buckets(),
860 elems_left: self.size(),
864 pub fn iter_mut(&mut self) -> IterMut<K, V> {
866 iter: self.raw_buckets(),
867 elems_left: self.size(),
868 _marker: marker::PhantomData,
872 pub fn into_iter(self) -> IntoIter<K, V> {
873 let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
874 // Replace the marker regardless of lifetime bounds on parameters.
878 hashes_end: hashes_end,
879 marker: marker::PhantomData,
885 pub fn drain(&mut self) -> Drain<K, V> {
886 let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
887 // Replace the marker regardless of lifetime bounds on parameters.
891 hashes_end: hashes_end,
892 marker: marker::PhantomData,
894 table: unsafe { Shared::new(self) },
895 marker: marker::PhantomData,
899 /// Returns an iterator that copies out each entry. Used while the table
900 /// is being dropped.
901 unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
902 let raw_bucket = self.first_bucket_raw();
904 raw: raw_bucket.offset(self.capacity as isize),
905 hashes_end: raw_bucket.hash,
906 elems_left: self.size,
907 marker: marker::PhantomData,
911 /// Set the table tag
912 pub fn set_tag(&mut self, value: bool) {
913 self.hashes.set_tag(value)
916 /// Get the table tag
917 pub fn tag(&self) -> bool {
922 /// A raw iterator. The basis for some other iterators in this module. Although
923 /// this interface is safe, it's not used outside this module.
924 struct RawBuckets<'a, K, V> {
925 raw: RawBucket<K, V>,
926 hashes_end: *mut HashUint,
928 // Strictly speaking, this should be &'a (K,V), but that would
929 // require that K:'a, and we often use RawBuckets<'static...> for
930 // move iterations, so that messes up a lot of other things. So
931 // just use `&'a (K,V)` as this is not a publicly exposed type
933 marker: marker::PhantomData<&'a ()>,
936 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
937 impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
938 fn clone(&self) -> RawBuckets<'a, K, V> {
941 hashes_end: self.hashes_end,
942 marker: marker::PhantomData,
948 impl<'a, K, V> Iterator for RawBuckets<'a, K, V> {
949 type Item = RawBucket<K, V>;
951 fn next(&mut self) -> Option<RawBucket<K, V>> {
952 while self.raw.hash != self.hashes_end {
954 // We are swapping out the pointer to a bucket and replacing
955 // it with the pointer to the next one.
956 let prev = ptr::replace(&mut self.raw, self.raw.offset(1));
957 if *prev.hash != EMPTY_BUCKET {
967 /// An iterator that moves out buckets in reverse order. It leaves the table
968 /// in an inconsistent state and should only be used for dropping
969 /// the table's remaining entries. It's used in the implementation of Drop.
970 struct RevMoveBuckets<'a, K, V> {
971 raw: RawBucket<K, V>,
972 hashes_end: *mut HashUint,
975 // As above, `&'a (K,V)` would seem better, but we often use
976 // 'static for the lifetime, and this is not a publicly exposed
978 marker: marker::PhantomData<&'a ()>,
981 impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
984 fn next(&mut self) -> Option<(K, V)> {
985 if self.elems_left == 0 {
990 debug_assert!(self.raw.hash != self.hashes_end);
993 self.raw = self.raw.offset(-1);
995 if *self.raw.hash != EMPTY_BUCKET {
996 self.elems_left -= 1;
997 return Some(ptr::read(self.raw.pair));
1004 /// Iterator over shared references to entries in a table.
1005 pub struct Iter<'a, K: 'a, V: 'a> {
1006 iter: RawBuckets<'a, K, V>,
1010 unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
1011 unsafe impl<'a, K: Sync, V: Sync> Send for Iter<'a, K, V> {}
1013 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
1014 impl<'a, K, V> Clone for Iter<'a, K, V> {
1015 fn clone(&self) -> Iter<'a, K, V> {
1017 iter: self.iter.clone(),
1018 elems_left: self.elems_left,
1024 /// Iterator over mutable references to entries in a table.
1025 pub struct IterMut<'a, K: 'a, V: 'a> {
1026 iter: RawBuckets<'a, K, V>,
1028 // To ensure invariance with respect to V
1029 _marker: marker::PhantomData<&'a mut V>,
1032 unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
1033 // Both K: Sync and K: Send are correct for IterMut's Send impl,
1034 // but Send is the more useful bound
1035 unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
1037 impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> {
1038 pub fn iter(&self) -> Iter<K, V> {
1040 iter: self.iter.clone(),
1041 elems_left: self.elems_left,
1046 /// Iterator over the entries in a table, consuming the table.
1047 pub struct IntoIter<K, V> {
1048 table: RawTable<K, V>,
1049 iter: RawBuckets<'static, K, V>,
1052 unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {}
1053 unsafe impl<K: Send, V: Send> Send for IntoIter<K, V> {}
1055 impl<K, V> IntoIter<K, V> {
1056 pub fn iter(&self) -> Iter<K, V> {
1058 iter: self.iter.clone(),
1059 elems_left: self.table.size,
1064 /// Iterator over the entries in a table, clearing the table.
1065 pub struct Drain<'a, K: 'a, V: 'a> {
1066 table: Shared<RawTable<K, V>>,
1067 iter: RawBuckets<'static, K, V>,
1068 marker: marker::PhantomData<&'a RawTable<K, V>>,
1071 unsafe impl<'a, K: Sync, V: Sync> Sync for Drain<'a, K, V> {}
1072 unsafe impl<'a, K: Send, V: Send> Send for Drain<'a, K, V> {}
1074 impl<'a, K, V> Drain<'a, K, V> {
1075 pub fn iter(&self) -> Iter<K, V> {
1078 iter: self.iter.clone(),
1079 elems_left: (**self.table).size,
1085 impl<'a, K, V> Iterator for Iter<'a, K, V> {
1086 type Item = (&'a K, &'a V);
1088 fn next(&mut self) -> Option<(&'a K, &'a V)> {
1089 self.iter.next().map(|bucket| {
1090 self.elems_left -= 1;
1091 unsafe { (&(*bucket.pair).0, &(*bucket.pair).1) }
1095 fn size_hint(&self) -> (usize, Option<usize>) {
1096 (self.elems_left, Some(self.elems_left))
1099 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
1100 fn len(&self) -> usize {
1105 impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1106 type Item = (&'a K, &'a mut V);
1108 fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1109 self.iter.next().map(|bucket| {
1110 self.elems_left -= 1;
1111 let pair_mut = bucket.pair as *mut (K, V);
1112 unsafe { (&(*pair_mut).0, &mut (*pair_mut).1) }
1116 fn size_hint(&self) -> (usize, Option<usize>) {
1117 (self.elems_left, Some(self.elems_left))
1120 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
1121 fn len(&self) -> usize {
1126 impl<K, V> Iterator for IntoIter<K, V> {
1127 type Item = (SafeHash, K, V);
1129 fn next(&mut self) -> Option<(SafeHash, K, V)> {
1130 self.iter.next().map(|bucket| {
1131 self.table.size -= 1;
1133 let (k, v) = ptr::read(bucket.pair);
1134 (SafeHash { hash: *bucket.hash }, k, v)
1139 fn size_hint(&self) -> (usize, Option<usize>) {
1140 let size = self.table.size();
1144 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
1145 fn len(&self) -> usize {
1150 impl<'a, K, V> Iterator for Drain<'a, K, V> {
1151 type Item = (SafeHash, K, V);
1154 fn next(&mut self) -> Option<(SafeHash, K, V)> {
1155 self.iter.next().map(|bucket| {
1157 (**self.table).size -= 1;
1158 let (k, v) = ptr::read(bucket.pair);
1159 (SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) }, k, v)
1164 fn size_hint(&self) -> (usize, Option<usize>) {
1165 let size = unsafe { (**self.table).size() };
1169 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
1170 fn len(&self) -> usize {
1171 unsafe { (**self.table).size() }
1175 impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
1176 fn drop(&mut self) {
1181 impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
1182 fn clone(&self) -> RawTable<K, V> {
1184 let mut new_ht = RawTable::new_uninitialized(self.capacity());
1187 let cap = self.capacity();
1188 let mut new_buckets = Bucket::first(&mut new_ht);
1189 let mut buckets = Bucket::first(self);
1190 while buckets.index() != cap {
1191 match buckets.peek() {
1194 let (k, v) = full.read();
1195 (full.hash(), k.clone(), v.clone())
1197 *new_buckets.raw.hash = h.inspect();
1198 ptr::write(new_buckets.raw.pair as *mut (K, V), (k, v));
1201 *new_buckets.raw.hash = EMPTY_BUCKET;
1209 new_ht.size = self.size();
1216 unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
1217 fn drop(&mut self) {
1218 if self.capacity == 0 {
1222 // This is done in reverse because we've likely partially taken
1223 // some elements out with `.into_iter()` from the front.
1224 // Check if the size is 0, so we don't do a useless scan when
1225 // dropping empty tables such as on resize.
1226 // Also avoid double drop of elements that have been already moved out.
1228 if needs_drop::<(K, V)>() {
1229 // avoid linear runtime for types that don't need drop
1230 for _ in self.rev_move_buckets() {}
1234 let hashes_size = self.capacity * size_of::<HashUint>();
1235 let pairs_size = self.capacity * size_of::<(K, V)>();
1236 let (align, _, size, oflo) = calculate_allocation(hashes_size,
1237 align_of::<HashUint>(),
1239 align_of::<(K, V)>());
1241 debug_assert!(!oflo, "should be impossible");
1244 deallocate(self.hashes.ptr() as *mut u8, size, align);
1245 // Remember how everything was allocated out of one buffer
1246 // during initialization? We only need one call to free here.