]> git.lizzy.rs Git - rust.git/blob - src/libstd/collections/hash/table.rs
Auto merge of #58406 - Disasm:rv64-support, r=nagisa
[rust.git] / src / libstd / collections / hash / table.rs
1 use alloc::{Global, Alloc, Layout, LayoutErr, handle_alloc_error};
2 use collections::CollectionAllocErr;
3 use hash::{BuildHasher, Hash, Hasher};
4 use marker;
5 use mem::{size_of, needs_drop};
6 use mem;
7 use ops::{Deref, DerefMut};
8 use ptr::{self, Unique, NonNull};
9 use hint;
10
11 use self::BucketState::*;
12
13 /// Integer type used for stored hash values.
14 ///
15 /// No more than bit_width(usize) bits are needed to select a bucket.
16 ///
17 /// The most significant bit is ours to use for tagging `SafeHash`.
18 ///
19 /// (Even if we could have usize::MAX bytes allocated for buckets,
20 /// each bucket stores at least a `HashUint`, so there can be no more than
21 /// usize::MAX / size_of(usize) buckets.)
22 type HashUint = usize;
23
24 const EMPTY_BUCKET: HashUint = 0;
25 const EMPTY: usize = 1;
26
27 /// Special `Unique<HashUint>` that uses the lower bit of the pointer
28 /// to expose a boolean tag.
29 /// Note: when the pointer is initialized to EMPTY `.ptr()` will return
30 /// null and the tag functions shouldn't be used.
31 struct TaggedHashUintPtr(Unique<HashUint>);
32
33 impl TaggedHashUintPtr {
34     #[inline]
35     unsafe fn new(ptr: *mut HashUint) -> Self {
36         debug_assert!(ptr as usize & 1 == 0 || ptr as usize == EMPTY as usize);
37         TaggedHashUintPtr(Unique::new_unchecked(ptr))
38     }
39
40     #[inline]
41     fn set_tag(&mut self, value: bool) {
42         let mut usize_ptr = self.0.as_ptr() as usize;
43         unsafe {
44             if value {
45                 usize_ptr |= 1;
46             } else {
47                 usize_ptr &= !1;
48             }
49             self.0 = Unique::new_unchecked(usize_ptr as *mut HashUint)
50         }
51     }
52
53     #[inline]
54     fn tag(&self) -> bool {
55         (self.0.as_ptr() as usize) & 1 == 1
56     }
57
58     #[inline]
59     fn ptr(&self) -> *mut HashUint {
60         (self.0.as_ptr() as usize & !1) as *mut HashUint
61     }
62 }
63
64 /// The raw hashtable, providing safe-ish access to the unzipped and highly
65 /// optimized arrays of hashes, and key-value pairs.
66 ///
67 /// This design is a lot faster than the naive
68 /// `Vec<Option<(u64, K, V)>>`, because we don't pay for the overhead of an
69 /// option on every element, and we get a generally more cache-aware design.
70 ///
71 /// Essential invariants of this structure:
72 ///
73 ///   - if `t.hashes[i] == EMPTY_BUCKET`, then `Bucket::at_index(&t, i).raw`
74 ///     points to 'undefined' contents. Don't read from it. This invariant is
75 ///     enforced outside this module with the `EmptyBucket`, `FullBucket`,
76 ///     and `SafeHash` types.
77 ///
78 ///   - An `EmptyBucket` is only constructed at an index with
79 ///     a hash of EMPTY_BUCKET.
80 ///
81 ///   - A `FullBucket` is only constructed at an index with a
82 ///     non-EMPTY_BUCKET hash.
83 ///
84 ///   - A `SafeHash` is only constructed for non-`EMPTY_BUCKET` hash. We get
85 ///     around hashes of zero by changing them to 0x8000_0000_0000_0000,
86 ///     which will likely map to the same bucket, while not being confused
87 ///     with "empty".
88 ///
89 ///   - Both "arrays represented by pointers" are the same length:
90 ///     `capacity`. This is set at creation and never changes. The arrays
91 ///     are unzipped and are more cache aware (scanning through 8 hashes
92 ///     brings in at most 2 cache lines, since they're all right beside each
93 ///     other). This layout may waste space in padding such as in a map from
94 ///     u64 to u8, but is a more cache conscious layout as the key-value pairs
95 ///     are only very shortly probed and the desired value will be in the same
96 ///     or next cache line.
97 ///
98 /// You can kind of think of this module/data structure as a safe wrapper
99 /// around just the "table" part of the hashtable. It enforces some
100 /// invariants at the type level and employs some performance trickery,
101 /// but in general is just a tricked out `Vec<Option<(u64, K, V)>>`.
102 ///
103 /// The hashtable also exposes a special boolean tag. The tag defaults to false
104 /// when the RawTable is created and is accessible with the `tag` and `set_tag`
105 /// functions.
106 pub struct RawTable<K, V> {
107     capacity_mask: usize,
108     size: usize,
109     hashes: TaggedHashUintPtr,
110
111     // Because K/V do not appear directly in any of the types in the struct,
112     // inform rustc that in fact instances of K and V are reachable from here.
113     marker: marker::PhantomData<(K, V)>,
114 }
115
116 // An unsafe view of a RawTable bucket
117 // Valid indexes are within [0..table_capacity)
118 pub struct RawBucket<K, V> {
119     hash_start: *mut HashUint,
120     // We use *const to ensure covariance with respect to K and V
121     pair_start: *const (K, V),
122     idx: usize,
123     _marker: marker::PhantomData<(K, V)>,
124 }
125
126 impl<K, V> Copy for RawBucket<K, V> {}
127 impl<K, V> Clone for RawBucket<K, V> {
128     fn clone(&self) -> RawBucket<K, V> {
129         *self
130     }
131 }
132
133 pub struct Bucket<K, V, M> {
134     raw: RawBucket<K, V>,
135     table: M,
136 }
137
138 impl<K, V, M: Copy> Copy for Bucket<K, V, M> {}
139 impl<K, V, M: Copy> Clone for Bucket<K, V, M> {
140     fn clone(&self) -> Bucket<K, V, M> {
141         *self
142     }
143 }
144
145 pub struct EmptyBucket<K, V, M> {
146     raw: RawBucket<K, V>,
147     table: M,
148 }
149
150 pub struct FullBucket<K, V, M> {
151     raw: RawBucket<K, V>,
152     table: M,
153 }
154
155 pub type FullBucketMut<'table, K, V> = FullBucket<K, V, &'table mut RawTable<K, V>>;
156
157 pub enum BucketState<K, V, M> {
158     Empty(EmptyBucket<K, V, M>),
159     Full(FullBucket<K, V, M>),
160 }
161
162 // A GapThenFull encapsulates the state of two consecutive buckets at once.
163 // The first bucket, called the gap, is known to be empty.
164 // The second bucket is full.
165 pub struct GapThenFull<K, V, M> {
166     gap: EmptyBucket<K, V, ()>,
167     full: FullBucket<K, V, M>,
168 }
169
170 /// A hash that is not zero, since we use a hash of zero to represent empty
171 /// buckets.
172 #[derive(PartialEq, Copy, Clone)]
173 pub struct SafeHash {
174     hash: HashUint,
175 }
176
177 impl SafeHash {
178     /// Peek at the hash value, which is guaranteed to be non-zero.
179     #[inline(always)]
180     pub fn inspect(&self) -> HashUint {
181         self.hash
182     }
183
184     #[inline(always)]
185     pub fn new(hash: u64) -> Self {
186         // We need to avoid 0 in order to prevent collisions with
187         // EMPTY_HASH. We can maintain our precious uniform distribution
188         // of initial indexes by unconditionally setting the MSB,
189         // effectively reducing the hashes by one bit.
190         //
191         // Truncate hash to fit in `HashUint`.
192         let hash_bits = size_of::<HashUint>() * 8;
193         SafeHash { hash: (1 << (hash_bits - 1)) | (hash as HashUint) }
194     }
195 }
196
197 /// We need to remove hashes of 0. That's reserved for empty buckets.
198 /// This function wraps up `hash_keyed` to be the only way outside this
199 /// module to generate a SafeHash.
200 pub fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> SafeHash
201     where T: Hash,
202           S: BuildHasher
203 {
204     let mut state = hash_state.build_hasher();
205     t.hash(&mut state);
206     SafeHash::new(state.finish())
207 }
208
209 // `replace` casts a `*HashUint` to a `*SafeHash`. Since we statically
210 // ensure that a `FullBucket` points to an index with a non-zero hash,
211 // and a `SafeHash` is just a `HashUint` with a different name, this is
212 // safe.
213 //
214 // This test ensures that a `SafeHash` really IS the same size as a
215 // `HashUint`. If you need to change the size of `SafeHash` (and
216 // consequently made this test fail), `replace` needs to be
217 // modified to no longer assume this.
218 #[test]
219 fn can_alias_safehash_as_hash() {
220     assert_eq!(size_of::<SafeHash>(), size_of::<HashUint>())
221 }
222
223 // RawBucket methods are unsafe as it's possible to
224 // make a RawBucket point to invalid memory using safe code.
225 impl<K, V> RawBucket<K, V> {
226     unsafe fn hash(&self) -> *mut HashUint {
227         self.hash_start.add(self.idx)
228     }
229     unsafe fn pair(&self) -> *mut (K, V) {
230         self.pair_start.add(self.idx) as *mut (K, V)
231     }
232     unsafe fn hash_pair(&self) -> (*mut HashUint, *mut (K, V)) {
233         (self.hash(), self.pair())
234     }
235 }
236
237 // Buckets hold references to the table.
238 impl<K, V, M> FullBucket<K, V, M> {
239     /// Borrow a reference to the table.
240     pub fn table(&self) -> &M {
241         &self.table
242     }
243     /// Borrow a mutable reference to the table.
244     pub fn table_mut(&mut self) -> &mut M {
245         &mut self.table
246     }
247     /// Move out the reference to the table.
248     pub fn into_table(self) -> M {
249         self.table
250     }
251     /// Gets the raw index.
252     pub fn index(&self) -> usize {
253         self.raw.idx
254     }
255     /// Gets the raw bucket.
256     pub fn raw(&self) -> RawBucket<K, V> {
257         self.raw
258     }
259 }
260
261 impl<K, V, M> EmptyBucket<K, V, M> {
262     /// Borrow a reference to the table.
263     pub fn table(&self) -> &M {
264         &self.table
265     }
266     /// Borrow a mutable reference to the table.
267     pub fn table_mut(&mut self) -> &mut M {
268         &mut self.table
269     }
270 }
271
272 impl<K, V, M> Bucket<K, V, M> {
273     /// Gets the raw index.
274     pub fn index(&self) -> usize {
275         self.raw.idx
276     }
277     /// get the table.
278     pub fn into_table(self) -> M {
279         self.table
280     }
281 }
282
283 impl<K, V, M> Deref for FullBucket<K, V, M>
284     where M: Deref<Target = RawTable<K, V>>
285 {
286     type Target = RawTable<K, V>;
287     fn deref(&self) -> &RawTable<K, V> {
288         &self.table
289     }
290 }
291
292 /// `Put` is implemented for types which provide access to a table and cannot be invalidated
293 ///  by filling a bucket. A similar implementation for `Take` is possible.
294 pub trait Put<K, V> {
295     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V>;
296 }
297
298
299 impl<'t, K, V> Put<K, V> for &'t mut RawTable<K, V> {
300     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
301         *self
302     }
303 }
304
305 impl<K, V, M> Put<K, V> for Bucket<K, V, M>
306     where M: Put<K, V>
307 {
308     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
309         self.table.borrow_table_mut()
310     }
311 }
312
313 impl<K, V, M> Put<K, V> for FullBucket<K, V, M>
314     where M: Put<K, V>
315 {
316     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
317         self.table.borrow_table_mut()
318     }
319 }
320
321 impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
322     #[inline]
323     pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
324         Bucket::at_index(table, hash.inspect() as usize)
325     }
326
327     pub fn new_from(r: RawBucket<K, V>, t: M)
328         -> Bucket<K, V, M>
329     {
330         Bucket {
331             raw: r,
332             table: t,
333         }
334     }
335
336     #[inline]
337     pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
338         // if capacity is 0, then the RawBucket will be populated with bogus pointers.
339         // This is an uncommon case though, so avoid it in release builds.
340         debug_assert!(table.capacity() > 0,
341                       "Table should have capacity at this point");
342         let ib_index = ib_index & table.capacity_mask;
343         Bucket {
344             raw: table.raw_bucket_at(ib_index),
345             table,
346         }
347     }
348
349     pub fn first(table: M) -> Bucket<K, V, M> {
350         Bucket {
351             raw: table.raw_bucket_at(0),
352             table,
353         }
354     }
355
356     // "So a few of the first shall be last: for many be called,
357     // but few chosen."
358     //
359     // We'll most likely encounter a few buckets at the beginning that
360     // have their initial buckets near the end of the table. They were
361     // placed at the beginning as the probe wrapped around the table
362     // during insertion. We must skip forward to a bucket that won't
363     // get reinserted too early and won't unfairly steal others spot.
364     // This eliminates the need for robin hood.
365     pub fn head_bucket(table: M) -> Bucket<K, V, M> {
366         let mut bucket = Bucket::first(table);
367
368         loop {
369             bucket = match bucket.peek() {
370                 Full(full) => {
371                     if full.displacement() == 0 {
372                         // This bucket occupies its ideal spot.
373                         // It indicates the start of another "cluster".
374                         bucket = full.into_bucket();
375                         break;
376                     }
377                     // Leaving this bucket in the last cluster for later.
378                     full.into_bucket()
379                 }
380                 Empty(b) => {
381                     // Encountered a hole between clusters.
382                     b.into_bucket()
383                 }
384             };
385             bucket.next();
386         }
387         bucket
388     }
389
390     /// Reads a bucket at a given index, returning an enum indicating whether
391     /// it's initialized or not. You need to match on this enum to get
392     /// the appropriate types to call most of the other functions in
393     /// this module.
394     pub fn peek(self) -> BucketState<K, V, M> {
395         match unsafe { *self.raw.hash() } {
396             EMPTY_BUCKET => {
397                 Empty(EmptyBucket {
398                     raw: self.raw,
399                     table: self.table,
400                 })
401             }
402             _ => {
403                 Full(FullBucket {
404                     raw: self.raw,
405                     table: self.table,
406                 })
407             }
408         }
409     }
410
411     /// Modifies the bucket in place to make it point to the next slot.
412     pub fn next(&mut self) {
413         self.raw.idx = self.raw.idx.wrapping_add(1) & self.table.capacity_mask;
414     }
415
416     /// Modifies the bucket in place to make it point to the previous slot.
417     pub fn prev(&mut self) {
418         self.raw.idx = self.raw.idx.wrapping_sub(1) & self.table.capacity_mask;
419     }
420 }
421
422 impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
423     #[inline]
424     pub fn next(self) -> Bucket<K, V, M> {
425         let mut bucket = self.into_bucket();
426         bucket.next();
427         bucket
428     }
429
430     #[inline]
431     pub fn into_bucket(self) -> Bucket<K, V, M> {
432         Bucket {
433             raw: self.raw,
434             table: self.table,
435         }
436     }
437
438     pub fn gap_peek(self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
439         let gap = EmptyBucket {
440             raw: self.raw,
441             table: (),
442         };
443
444         match self.next().peek() {
445             Full(bucket) => {
446                 Ok(GapThenFull {
447                     gap,
448                     full: bucket,
449                 })
450             }
451             Empty(e) => Err(e.into_bucket()),
452         }
453     }
454 }
455
456 impl<K, V, M> EmptyBucket<K, V, M>
457     where M: Put<K, V>
458 {
459     /// Puts given key and value pair, along with the key's hash,
460     /// into this bucket in the hashtable. Note how `self` is 'moved' into
461     /// this function, because this slot will no longer be empty when
462     /// we return! A `FullBucket` is returned for later use, pointing to
463     /// the newly-filled slot in the hashtable.
464     ///
465     /// Use `make_hash` to construct a `SafeHash` to pass to this function.
466     pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
467         unsafe {
468             *self.raw.hash() = hash.inspect();
469             ptr::write(self.raw.pair(), (key, value));
470
471             self.table.borrow_table_mut().size += 1;
472         }
473
474         FullBucket {
475             raw: self.raw,
476             table: self.table,
477         }
478     }
479 }
480
481 impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
482     #[inline]
483     pub fn next(self) -> Bucket<K, V, M> {
484         let mut bucket = self.into_bucket();
485         bucket.next();
486         bucket
487     }
488
489     #[inline]
490     pub fn into_bucket(self) -> Bucket<K, V, M> {
491         Bucket {
492             raw: self.raw,
493             table: self.table,
494         }
495     }
496
497     /// Duplicates the current position. This can be useful for operations
498     /// on two or more buckets.
499     pub fn stash(self) -> FullBucket<K, V, Self> {
500         FullBucket {
501             raw: self.raw,
502             table: self,
503         }
504     }
505
506     /// Gets the distance between this bucket and the 'ideal' location
507     /// as determined by the key's hash stored in it.
508     ///
509     /// In the cited blog posts above, this is called the "distance to
510     /// initial bucket", or DIB. Also known as "probe count".
511     pub fn displacement(&self) -> usize {
512         // Calculates the distance one has to travel when going from
513         // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
514         // if the destination is not reached before the end of the table.
515         (self.raw.idx.wrapping_sub(self.hash().inspect() as usize)) & self.table.capacity_mask
516     }
517
518     #[inline]
519     pub fn hash(&self) -> SafeHash {
520         unsafe { SafeHash { hash: *self.raw.hash() } }
521     }
522
523     /// Gets references to the key and value at a given index.
524     pub fn read(&self) -> (&K, &V) {
525         unsafe {
526             let pair_ptr = self.raw.pair();
527             (&(*pair_ptr).0, &(*pair_ptr).1)
528         }
529     }
530 }
531
532 // We take a mutable reference to the table instead of accepting anything that
533 // implements `DerefMut` to prevent fn `take` from being called on `stash`ed
534 // buckets.
535 impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
536     /// Removes this bucket's key and value from the hashtable.
537     ///
538     /// This works similarly to `put`, building an `EmptyBucket` out of the
539     /// taken bucket.
540     pub fn take(self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
541         self.table.size -= 1;
542
543         unsafe {
544             *self.raw.hash() = EMPTY_BUCKET;
545             let (k, v) = ptr::read(self.raw.pair());
546             (EmptyBucket {
547                  raw: self.raw,
548                  table: self.table,
549              },
550             k,
551             v)
552         }
553     }
554 }
555
556 // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases
557 // where `M` is a full bucket or table reference type with mutable access to the table.
558 impl<K, V, M> FullBucket<K, V, M>
559     where M: Put<K, V>
560 {
561     pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
562         unsafe {
563             let old_hash = ptr::replace(self.raw.hash() as *mut SafeHash, h);
564             let (old_key, old_val) = ptr::replace(self.raw.pair(), (k, v));
565
566             (old_hash, old_key, old_val)
567         }
568     }
569 }
570
571 impl<K, V, M> FullBucket<K, V, M>
572     where M: Deref<Target = RawTable<K, V>> + DerefMut
573 {
574     /// Gets mutable references to the key and value at a given index.
575     pub fn read_mut(&mut self) -> (&mut K, &mut V) {
576         unsafe {
577             let pair_ptr = self.raw.pair();
578             (&mut (*pair_ptr).0, &mut (*pair_ptr).1)
579         }
580     }
581 }
582
583 impl<'t, K, V, M> FullBucket<K, V, M>
584     where M: Deref<Target = RawTable<K, V>> + 't
585 {
586     /// Exchange a bucket state for immutable references into the table.
587     /// Because the underlying reference to the table is also consumed,
588     /// no further changes to the structure of the table are possible;
589     /// in exchange for this, the returned references have a longer lifetime
590     /// than the references returned by `read()`.
591     pub fn into_refs(self) -> (&'t K, &'t V) {
592         unsafe {
593             let pair_ptr = self.raw.pair();
594             (&(*pair_ptr).0, &(*pair_ptr).1)
595         }
596     }
597 }
598
599 impl<'t, K, V, M> FullBucket<K, V, M>
600     where M: Deref<Target = RawTable<K, V>> + DerefMut + 't
601 {
602     /// This works similarly to `into_refs`, exchanging a bucket state
603     /// for mutable references into the table.
604     pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
605         unsafe {
606             let pair_ptr = self.raw.pair();
607             (&mut (*pair_ptr).0, &mut (*pair_ptr).1)
608         }
609     }
610 }
611
612 impl<K, V, M> GapThenFull<K, V, M>
613     where M: Deref<Target = RawTable<K, V>>
614 {
615     #[inline]
616     pub fn full(&self) -> &FullBucket<K, V, M> {
617         &self.full
618     }
619
620     pub fn into_table(self) -> M {
621         self.full.into_table()
622     }
623
624     pub fn shift(mut self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
625         unsafe {
626             let (gap_hash, gap_pair) = self.gap.raw.hash_pair();
627             let (full_hash, full_pair) = self.full.raw.hash_pair();
628             *gap_hash = mem::replace(&mut *full_hash, EMPTY_BUCKET);
629             ptr::copy_nonoverlapping(full_pair, gap_pair, 1);
630         }
631
632         let FullBucket { raw: prev_raw, .. } = self.full;
633
634         match self.full.next().peek() {
635             Full(bucket) => {
636                 self.gap.raw = prev_raw;
637
638                 self.full = bucket;
639
640                 Ok(self)
641             }
642             Empty(b) => Err(b.into_bucket()),
643         }
644     }
645 }
646
647 // Returns a Layout which describes the allocation required for a hash table,
648 // and the offset of the array of (key, value) pairs in the allocation.
649 #[inline(always)]
650 fn calculate_layout<K, V>(capacity: usize) -> Result<(Layout, usize), LayoutErr> {
651     let hashes = Layout::array::<HashUint>(capacity)?;
652     let pairs = Layout::array::<(K, V)>(capacity)?;
653     hashes.extend(pairs).map(|(layout, _)| {
654         // LLVM seems to have trouble properly const-propagating pairs.align(),
655         // possibly due to the use of NonZeroUsize. This little hack allows it
656         // to generate optimal code.
657         //
658         // See https://github.com/rust-lang/rust/issues/51346 for more details.
659         (
660             layout,
661             hashes.size() + hashes.padding_needed_for(mem::align_of::<(K, V)>()),
662         )
663     })
664 }
665
666 pub(crate) enum Fallibility {
667     Fallible,
668     Infallible,
669 }
670
671 use self::Fallibility::*;
672
673 impl<K, V> RawTable<K, V> {
674     /// Does not initialize the buckets. The caller should ensure they,
675     /// at the very least, set every hash to EMPTY_BUCKET.
676     /// Returns an error if it cannot allocate or capacity overflows.
677     unsafe fn new_uninitialized_internal(
678         capacity: usize,
679         fallibility: Fallibility,
680     ) -> Result<RawTable<K, V>, CollectionAllocErr> {
681         if capacity == 0 {
682             return Ok(RawTable {
683                 size: 0,
684                 capacity_mask: capacity.wrapping_sub(1),
685                 hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint),
686                 marker: marker::PhantomData,
687             });
688         }
689
690         // Allocating hashmaps is a little tricky. We need to allocate two
691         // arrays, but since we know their sizes and alignments up front,
692         // we just allocate a single array, and then have the subarrays
693         // point into it.
694         let (layout, _) = calculate_layout::<K, V>(capacity)?;
695         let buffer = Global.alloc(layout).map_err(|e| match fallibility {
696             Infallible => handle_alloc_error(layout),
697             Fallible => e,
698         })?;
699
700         Ok(RawTable {
701             capacity_mask: capacity.wrapping_sub(1),
702             size: 0,
703             hashes: TaggedHashUintPtr::new(buffer.cast().as_ptr()),
704             marker: marker::PhantomData,
705         })
706     }
707
708     /// Does not initialize the buckets. The caller should ensure they,
709     /// at the very least, set every hash to EMPTY_BUCKET.
710     unsafe fn new_uninitialized(capacity: usize) -> RawTable<K, V> {
711         match Self::new_uninitialized_internal(capacity, Infallible) {
712             Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"),
713             Err(CollectionAllocErr::AllocErr) => unreachable!(),
714             Ok(table) => { table }
715         }
716     }
717
718     #[inline(always)]
719     fn raw_bucket_at(&self, index: usize) -> RawBucket<K, V> {
720         let (_, pairs_offset) = calculate_layout::<K, V>(self.capacity())
721             .unwrap_or_else(|_| unsafe { hint::unreachable_unchecked() });
722         let buffer = self.hashes.ptr() as *mut u8;
723         unsafe {
724             RawBucket {
725                 hash_start: buffer as *mut HashUint,
726                 pair_start: buffer.add(pairs_offset) as *const (K, V),
727                 idx: index,
728                 _marker: marker::PhantomData,
729             }
730         }
731     }
732
733     #[inline]
734     fn new_internal(
735         capacity: usize,
736         fallibility: Fallibility,
737     ) -> Result<RawTable<K, V>, CollectionAllocErr> {
738         unsafe {
739             let ret = RawTable::new_uninitialized_internal(capacity, fallibility)?;
740             if capacity > 0 {
741                 ptr::write_bytes(ret.hashes.ptr(), 0, capacity);
742             }
743             Ok(ret)
744         }
745     }
746
747     /// Tries to create a new raw table from a given capacity. If it cannot allocate,
748     /// it returns with AllocErr.
749     #[inline]
750     pub fn try_new(capacity: usize) -> Result<RawTable<K, V>, CollectionAllocErr> {
751         Self::new_internal(capacity, Fallible)
752     }
753
754     /// Creates a new raw table from a given capacity. All buckets are
755     /// initially empty.
756     #[inline]
757     pub fn new(capacity: usize) -> RawTable<K, V> {
758         match Self::new_internal(capacity, Infallible) {
759             Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"),
760             Err(CollectionAllocErr::AllocErr) => unreachable!(),
761             Ok(table) => { table }
762         }
763     }
764
765     /// The hashtable's capacity, similar to a vector's.
766     pub fn capacity(&self) -> usize {
767         self.capacity_mask.wrapping_add(1)
768     }
769
770     /// The number of elements ever `put` in the hashtable, minus the number
771     /// of elements ever `take`n.
772     pub fn size(&self) -> usize {
773         self.size
774     }
775
776     fn raw_buckets(&self) -> RawBuckets<K, V> {
777         RawBuckets {
778             raw: self.raw_bucket_at(0),
779             elems_left: self.size,
780             marker: marker::PhantomData,
781         }
782     }
783
784     pub fn iter(&self) -> Iter<K, V> {
785         Iter {
786             iter: self.raw_buckets(),
787         }
788     }
789
790     pub fn iter_mut(&mut self) -> IterMut<K, V> {
791         IterMut {
792             iter: self.raw_buckets(),
793             _marker: marker::PhantomData,
794         }
795     }
796
797     pub fn into_iter(self) -> IntoIter<K, V> {
798         let RawBuckets { raw, elems_left, .. } = self.raw_buckets();
799         // Replace the marker regardless of lifetime bounds on parameters.
800         IntoIter {
801             iter: RawBuckets {
802                 raw,
803                 elems_left,
804                 marker: marker::PhantomData,
805             },
806             table: self,
807         }
808     }
809
810     pub fn drain(&mut self) -> Drain<K, V> {
811         let RawBuckets { raw, elems_left, .. } = self.raw_buckets();
812         // Replace the marker regardless of lifetime bounds on parameters.
813         Drain {
814             iter: RawBuckets {
815                 raw,
816                 elems_left,
817                 marker: marker::PhantomData,
818             },
819             table: NonNull::from(self),
820             marker: marker::PhantomData,
821         }
822     }
823
824     /// Drops buckets in reverse order. It leaves the table in an inconsistent
825     /// state and should only be used for dropping the table's remaining
826     /// entries. It's used in the implementation of Drop.
827     unsafe fn rev_drop_buckets(&mut self) {
828         // initialize the raw bucket past the end of the table
829         let mut raw = self.raw_bucket_at(self.capacity());
830         let mut elems_left = self.size;
831
832         while elems_left != 0 {
833             raw.idx -= 1;
834
835             if *raw.hash() != EMPTY_BUCKET {
836                 elems_left -= 1;
837                 ptr::drop_in_place(raw.pair());
838             }
839         }
840     }
841
842     /// Sets the table tag.
843     pub fn set_tag(&mut self, value: bool) {
844         self.hashes.set_tag(value)
845     }
846
847     /// Gets the table tag.
848     pub fn tag(&self) -> bool {
849         self.hashes.tag()
850     }
851 }
852
853 /// A raw iterator. The basis for some other iterators in this module. Although
854 /// this interface is safe, it's not used outside this module.
855 struct RawBuckets<'a, K, V> {
856     raw: RawBucket<K, V>,
857     elems_left: usize,
858
859     // Strictly speaking, this should be &'a (K,V), but that would
860     // require that K:'a, and we often use RawBuckets<'static...> for
861     // move iterations, so that messes up a lot of other things. So
862     // just use `&'a (K,V)` as this is not a publicly exposed type
863     // anyway.
864     marker: marker::PhantomData<&'a ()>,
865 }
866
867 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
868 impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
869     fn clone(&self) -> RawBuckets<'a, K, V> {
870         RawBuckets {
871             raw: self.raw,
872             elems_left: self.elems_left,
873             marker: marker::PhantomData,
874         }
875     }
876 }
877
878
879 impl<'a, K, V> Iterator for RawBuckets<'a, K, V> {
880     type Item = RawBucket<K, V>;
881
882     fn next(&mut self) -> Option<RawBucket<K, V>> {
883         if self.elems_left == 0 {
884             return None;
885         }
886
887         loop {
888             unsafe {
889                 let item = self.raw;
890                 self.raw.idx += 1;
891                 if *item.hash() != EMPTY_BUCKET {
892                     self.elems_left -= 1;
893                     return Some(item);
894                 }
895             }
896         }
897     }
898
899     fn size_hint(&self) -> (usize, Option<usize>) {
900         (self.elems_left, Some(self.elems_left))
901     }
902 }
903
904 impl<'a, K, V> ExactSizeIterator for RawBuckets<'a, K, V> {
905     fn len(&self) -> usize {
906         self.elems_left
907     }
908 }
909
910 /// Iterator over shared references to entries in a table.
911 pub struct Iter<'a, K: 'a, V: 'a> {
912     iter: RawBuckets<'a, K, V>,
913 }
914
915 unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
916 unsafe impl<'a, K: Sync, V: Sync> Send for Iter<'a, K, V> {}
917
918 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
919 impl<'a, K, V> Clone for Iter<'a, K, V> {
920     fn clone(&self) -> Iter<'a, K, V> {
921         Iter {
922             iter: self.iter.clone(),
923         }
924     }
925 }
926
927 /// Iterator over mutable references to entries in a table.
928 pub struct IterMut<'a, K: 'a, V: 'a> {
929     iter: RawBuckets<'a, K, V>,
930     // To ensure invariance with respect to V
931     _marker: marker::PhantomData<&'a mut V>,
932 }
933
934 unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
935 // Both K: Sync and K: Send are correct for IterMut's Send impl,
936 // but Send is the more useful bound
937 unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
938
939 impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> {
940     pub fn iter(&self) -> Iter<K, V> {
941         Iter {
942             iter: self.iter.clone(),
943         }
944     }
945 }
946
947 /// Iterator over the entries in a table, consuming the table.
948 pub struct IntoIter<K, V> {
949     table: RawTable<K, V>,
950     iter: RawBuckets<'static, K, V>,
951 }
952
953 unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {}
954 unsafe impl<K: Send, V: Send> Send for IntoIter<K, V> {}
955
956 impl<K, V> IntoIter<K, V> {
957     pub fn iter(&self) -> Iter<K, V> {
958         Iter {
959             iter: self.iter.clone(),
960         }
961     }
962 }
963
964 /// Iterator over the entries in a table, clearing the table.
965 pub struct Drain<'a, K: 'a, V: 'a> {
966     table: NonNull<RawTable<K, V>>,
967     iter: RawBuckets<'static, K, V>,
968     marker: marker::PhantomData<&'a RawTable<K, V>>,
969 }
970
971 unsafe impl<'a, K: Sync, V: Sync> Sync for Drain<'a, K, V> {}
972 unsafe impl<'a, K: Send, V: Send> Send for Drain<'a, K, V> {}
973
974 impl<'a, K, V> Drain<'a, K, V> {
975     pub fn iter(&self) -> Iter<K, V> {
976         Iter {
977             iter: self.iter.clone(),
978         }
979     }
980 }
981
982 impl<'a, K, V> Iterator for Iter<'a, K, V> {
983     type Item = (&'a K, &'a V);
984
985     fn next(&mut self) -> Option<(&'a K, &'a V)> {
986         self.iter.next().map(|raw| unsafe {
987             let pair_ptr = raw.pair();
988             (&(*pair_ptr).0, &(*pair_ptr).1)
989         })
990     }
991
992     fn size_hint(&self) -> (usize, Option<usize>) {
993         self.iter.size_hint()
994     }
995 }
996
997 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
998     fn len(&self) -> usize {
999         self.iter.len()
1000     }
1001 }
1002
1003 impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1004     type Item = (&'a K, &'a mut V);
1005
1006     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1007         self.iter.next().map(|raw| unsafe {
1008             let pair_ptr = raw.pair();
1009             (&(*pair_ptr).0, &mut (*pair_ptr).1)
1010         })
1011     }
1012
1013     fn size_hint(&self) -> (usize, Option<usize>) {
1014         self.iter.size_hint()
1015     }
1016 }
1017
1018 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
1019     fn len(&self) -> usize {
1020         self.iter.len()
1021     }
1022 }
1023
1024 impl<K, V> Iterator for IntoIter<K, V> {
1025     type Item = (SafeHash, K, V);
1026
1027     fn next(&mut self) -> Option<(SafeHash, K, V)> {
1028         self.iter.next().map(|raw| {
1029             self.table.size -= 1;
1030             unsafe {
1031                 let (k, v) = ptr::read(raw.pair());
1032                 (SafeHash { hash: *raw.hash() }, k, v)
1033             }
1034         })
1035     }
1036
1037     fn size_hint(&self) -> (usize, Option<usize>) {
1038         self.iter.size_hint()
1039     }
1040 }
1041
1042 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
1043     fn len(&self) -> usize {
1044         self.iter().len()
1045     }
1046 }
1047
1048 impl<'a, K, V> Iterator for Drain<'a, K, V> {
1049     type Item = (SafeHash, K, V);
1050
1051     #[inline]
1052     fn next(&mut self) -> Option<(SafeHash, K, V)> {
1053         self.iter.next().map(|raw| {
1054             unsafe {
1055                 self.table.as_mut().size -= 1;
1056                 let (k, v) = ptr::read(raw.pair());
1057                 (SafeHash { hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET) }, k, v)
1058             }
1059         })
1060     }
1061
1062     fn size_hint(&self) -> (usize, Option<usize>) {
1063         self.iter.size_hint()
1064     }
1065 }
1066
1067 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
1068     fn len(&self) -> usize {
1069         self.iter.len()
1070     }
1071 }
1072
1073 impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
1074     fn drop(&mut self) {
1075         self.for_each(drop);
1076     }
1077 }
1078
1079 impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
1080     fn clone(&self) -> RawTable<K, V> {
1081         unsafe {
1082             let cap = self.capacity();
1083             let mut new_ht = RawTable::new_uninitialized(cap);
1084
1085             let mut new_buckets = new_ht.raw_bucket_at(0);
1086             let mut buckets = self.raw_bucket_at(0);
1087             while buckets.idx < cap {
1088                 *new_buckets.hash() = *buckets.hash();
1089                 if *new_buckets.hash() != EMPTY_BUCKET {
1090                     let pair_ptr = buckets.pair();
1091                     let kv = ((*pair_ptr).0.clone(), (*pair_ptr).1.clone());
1092                     ptr::write(new_buckets.pair(), kv);
1093                 }
1094                 buckets.idx += 1;
1095                 new_buckets.idx += 1;
1096             }
1097
1098             new_ht.size = self.size();
1099             new_ht.set_tag(self.tag());
1100
1101             new_ht
1102         }
1103     }
1104 }
1105
1106 unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
1107     fn drop(&mut self) {
1108         if self.capacity() == 0 {
1109             return;
1110         }
1111
1112         // This is done in reverse because we've likely partially taken
1113         // some elements out with `.into_iter()` from the front.
1114         // Check if the size is 0, so we don't do a useless scan when
1115         // dropping empty tables such as on resize.
1116         // Also avoid double drop of elements that have been already moved out.
1117         unsafe {
1118             if needs_drop::<(K, V)>() {
1119                 // avoid linear runtime for types that don't need drop
1120                 self.rev_drop_buckets();
1121             }
1122         }
1123
1124         let (layout, _) = calculate_layout::<K, V>(self.capacity())
1125             .unwrap_or_else(|_| unsafe { hint::unreachable_unchecked() });
1126         unsafe {
1127             Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).cast(), layout);
1128             // Remember how everything was allocated out of one buffer
1129             // during initialization? We only need one call to free here.
1130         }
1131     }
1132 }