]> git.lizzy.rs Git - rust.git/blob - src/libstd/collections/hash/table.rs
add inline attributes to stage 0 methods
[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 use alloc::heap::{EMPTY, allocate, deallocate};
12
13 use cmp;
14 use hash::{BuildHasher, Hash, Hasher};
15 use intrinsics::needs_drop;
16 use marker;
17 use mem::{align_of, size_of};
18 use mem;
19 use ops::{Deref, DerefMut};
20 use ptr::{self, Unique, Shared};
21
22 use self::BucketState::*;
23
24 /// Integer type used for stored hash values.
25 ///
26 /// No more than bit_width(usize) bits are needed to select a bucket.
27 ///
28 /// The most significant bit is ours to use for tagging `SafeHash`.
29 ///
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;
34
35 const EMPTY_BUCKET: HashUint = 0;
36
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>);
42
43 impl TaggedHashUintPtr {
44     #[inline]
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))
48     }
49
50     #[inline]
51     fn set_tag(&mut self, value: bool) {
52         let usize_ptr = &*self.0 as *const *mut HashUint as *mut usize;
53         unsafe {
54             if value {
55                 *usize_ptr |= 1;
56             } else {
57                 *usize_ptr &= !1;
58             }
59         }
60     }
61
62     #[inline]
63     fn tag(&self) -> bool {
64         (*self.0 as usize) & 1 == 1
65     }
66
67     #[inline]
68     fn ptr(&self) -> *mut HashUint {
69         (*self.0 as usize & !1) as *mut HashUint
70     }
71 }
72
73 /// The raw hashtable, providing safe-ish access to the unzipped and highly
74 /// optimized arrays of hashes, and key-value pairs.
75 ///
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.
79 ///
80 /// Essential invariants of this structure:
81 ///
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.
86 ///
87 ///   - An `EmptyBucket` is only constructed at an index with
88 ///     a hash of EMPTY_BUCKET.
89 ///
90 ///   - A `FullBucket` is only constructed at an index with a
91 ///     non-EMPTY_BUCKET hash.
92 ///
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
96 ///     with "empty".
97 ///
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.
106 ///
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)>>`.
111 ///
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`
114 /// functions.
115 pub struct RawTable<K, V> {
116     capacity: usize,
117     size: usize,
118     hashes: TaggedHashUintPtr,
119
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)>,
123 }
124
125 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
126 unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
127
128 pub struct RawBucket<K, V> {
129     hash: *mut HashUint,
130     // We use *const to ensure covariance with respect to K and V
131     pair: *const (K, V),
132     _marker: marker::PhantomData<(K, V)>,
133 }
134
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> {
138         *self
139     }
140 }
141
142 pub struct Bucket<K, V, M> {
143     raw: RawBucket<K, V>,
144     idx: usize,
145     table: M,
146 }
147
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> {
151         *self
152     }
153 }
154
155 pub struct EmptyBucket<K, V, M> {
156     raw: RawBucket<K, V>,
157     idx: usize,
158     table: M,
159 }
160
161 pub struct FullBucket<K, V, M> {
162     raw: RawBucket<K, V>,
163     idx: usize,
164     table: M,
165 }
166
167 pub type FullBucketMut<'table, K, V> = FullBucket<K, V, &'table mut RawTable<K, V>>;
168
169 pub enum BucketState<K, V, M> {
170     Empty(EmptyBucket<K, V, M>),
171     Full(FullBucket<K, V, M>),
172 }
173
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>,
180 }
181
182 /// A hash that is not zero, since we use a hash of zero to represent empty
183 /// buckets.
184 #[derive(PartialEq, Copy, Clone)]
185 pub struct SafeHash {
186     hash: HashUint,
187 }
188
189 impl SafeHash {
190     /// Peek at the hash value, which is guaranteed to be non-zero.
191     #[inline(always)]
192     pub fn inspect(&self) -> HashUint {
193         self.hash
194     }
195
196     #[inline(always)]
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.
202         //
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) }
206     }
207 }
208
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
213     where T: Hash,
214           S: BuildHasher
215 {
216     let mut state = hash_state.build_hasher();
217     t.hash(&mut state);
218     SafeHash::new(state.finish())
219 }
220
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
224 // safe.
225 //
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.
230 #[test]
231 fn can_alias_safehash_as_hash() {
232     assert_eq!(size_of::<SafeHash>(), size_of::<HashUint>())
233 }
234
235 impl<K, V> RawBucket<K, V> {
236     unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
237         RawBucket {
238             hash: self.hash.offset(count),
239             pair: self.pair.offset(count),
240             _marker: marker::PhantomData,
241         }
242     }
243 }
244
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 {
249         &self.table
250     }
251     /// Borrow a mutable reference to the table.
252     pub fn table_mut(&mut self) -> &mut M {
253         &mut self.table
254     }
255     /// Move out the reference to the table.
256     pub fn into_table(self) -> M {
257         self.table
258     }
259     /// Get the raw index.
260     pub fn index(&self) -> usize {
261         self.idx
262     }
263     /// Get the raw bucket.
264     pub fn raw(&self) -> RawBucket<K, V> {
265         self.raw
266     }
267 }
268
269 impl<K, V, M> EmptyBucket<K, V, M> {
270     /// Borrow a reference to the table.
271     pub fn table(&self) -> &M {
272         &self.table
273     }
274     /// Borrow a mutable reference to the table.
275     pub fn table_mut(&mut self) -> &mut M {
276         &mut self.table
277     }
278 }
279
280 impl<K, V, M> Bucket<K, V, M> {
281     /// Get the raw index.
282     pub fn index(&self) -> usize {
283         self.idx
284     }
285     /// get the table.
286     pub fn into_table(self) -> M {
287         self.table
288     }
289 }
290
291 impl<K, V, M> Deref for FullBucket<K, V, M>
292     where M: Deref<Target = RawTable<K, V>>
293 {
294     type Target = RawTable<K, V>;
295     fn deref(&self) -> &RawTable<K, V> {
296         &self.table
297     }
298 }
299
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>;
304 }
305
306
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> {
309         *self
310     }
311 }
312
313 impl<K, V, M> Put<K, V> for Bucket<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> Put<K, V> for FullBucket<K, V, M>
322     where M: Put<K, V>
323 {
324     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
325         self.table.borrow_table_mut()
326     }
327 }
328
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)
332     }
333
334     pub fn new_from(r: RawBucket<K, V>, i: usize, t: M)
335         -> Bucket<K, V, M>
336     {
337         Bucket {
338             raw: r,
339             idx: i,
340             table: t,
341         }
342     }
343
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);
350         Bucket {
351             raw: unsafe { table.first_bucket_raw().offset(ib_index as isize) },
352             idx: ib_index,
353             table: table,
354         }
355     }
356
357     pub fn first(table: M) -> Bucket<K, V, M> {
358         Bucket {
359             raw: table.first_bucket_raw(),
360             idx: 0,
361             table: table,
362         }
363     }
364
365     // "So a few of the first shall be last: for many be called,
366     // but few chosen."
367     //
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);
376
377         loop {
378             bucket = match bucket.peek() {
379                 Full(full) => {
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();
384                         break;
385                     }
386                     // Leaving this bucket in the last cluster for later.
387                     full.into_bucket()
388                 }
389                 Empty(b) => {
390                     // Encountered a hole between clusters.
391                     b.into_bucket()
392                 }
393             };
394             bucket.next();
395         }
396         bucket
397     }
398
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
402     /// this module.
403     pub fn peek(self) -> BucketState<K, V, M> {
404         match unsafe { *self.raw.hash } {
405             EMPTY_BUCKET => {
406                 Empty(EmptyBucket {
407                     raw: self.raw,
408                     idx: self.idx,
409                     table: self.table,
410                 })
411             }
412             _ => {
413                 Full(FullBucket {
414                     raw: self.raw,
415                     idx: self.idx,
416                     table: self.table,
417                 })
418             }
419         }
420     }
421
422     /// Modifies the bucket pointer in place to make it point to the next slot.
423     pub fn next(&mut self) {
424         self.idx += 1;
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 {
428             1 - range as isize
429         } else {
430             1
431         };
432         unsafe {
433             self.raw = self.raw.offset(dist);
434         }
435     }
436
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);
442         self.idx = new_idx;
443         unsafe {
444             self.raw = self.raw.offset(dist);
445         }
446     }
447 }
448
449 impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
450     #[inline]
451     pub fn next(self) -> Bucket<K, V, M> {
452         let mut bucket = self.into_bucket();
453         bucket.next();
454         bucket
455     }
456
457     #[inline]
458     pub fn into_bucket(self) -> Bucket<K, V, M> {
459         Bucket {
460             raw: self.raw,
461             idx: self.idx,
462             table: self.table,
463         }
464     }
465
466     pub fn gap_peek(self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
467         let gap = EmptyBucket {
468             raw: self.raw,
469             idx: self.idx,
470             table: (),
471         };
472
473         match self.next().peek() {
474             Full(bucket) => {
475                 Ok(GapThenFull {
476                     gap: gap,
477                     full: bucket,
478                 })
479             }
480             Empty(e) => Err(e.into_bucket()),
481         }
482     }
483 }
484
485 impl<K, V, M> EmptyBucket<K, V, M>
486     where M: Put<K, V>
487 {
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.
493     ///
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> {
496         unsafe {
497             *self.raw.hash = hash.inspect();
498             ptr::write(self.raw.pair as *mut (K, V), (key, value));
499
500             self.table.borrow_table_mut().size += 1;
501         }
502
503         FullBucket {
504             raw: self.raw,
505             idx: self.idx,
506             table: self.table,
507         }
508     }
509
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);
516
517         self.table.borrow_table_mut().size += 1;
518
519         FullBucket {
520             raw: self.raw,
521             idx: self.idx,
522             table: self.table,
523         }
524     }
525 }
526
527 impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
528     #[inline]
529     pub fn next(self) -> Bucket<K, V, M> {
530         let mut bucket = self.into_bucket();
531         bucket.next();
532         bucket
533     }
534
535     #[inline]
536     pub fn into_bucket(self) -> Bucket<K, V, M> {
537         Bucket {
538             raw: self.raw,
539             idx: self.idx,
540             table: self.table,
541         }
542     }
543
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> {
547         FullBucket {
548             raw: self.raw,
549             idx: self.idx,
550             table: self,
551         }
552     }
553
554     /// Get the distance between this bucket and the 'ideal' location
555     /// as determined by the key's hash stored in it.
556     ///
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)
564     }
565
566     #[inline]
567     pub fn hash(&self) -> SafeHash {
568         unsafe { SafeHash { hash: *self.raw.hash } }
569     }
570
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) }
574     }
575 }
576
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
579 // buckets.
580 impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
581     /// Removes this bucket's key and value from the hashtable.
582     ///
583     /// This works similarly to `put`, building an `EmptyBucket` out of the
584     /// taken bucket.
585     pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
586         self.table.size -= 1;
587
588         unsafe {
589             *self.raw.hash = EMPTY_BUCKET;
590             let (k, v) = ptr::read(self.raw.pair);
591             (EmptyBucket {
592                  raw: self.raw,
593                  idx: self.idx,
594                  table: self.table,
595              },
596             k,
597             v)
598         }
599     }
600
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;
606
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
610     }
611 }
612
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>
616     where M: Put<K, V>
617 {
618     pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
619         unsafe {
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));
622
623             (old_hash, old_key, old_val)
624         }
625     }
626 }
627
628 impl<K, V, M> FullBucket<K, V, M>
629     where M: Deref<Target = RawTable<K, V>> + DerefMut
630 {
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) }
635     }
636 }
637
638 impl<'t, K, V, M> FullBucket<K, V, M>
639     where M: Deref<Target = RawTable<K, V>> + 't
640 {
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) }
648     }
649 }
650
651 impl<'t, K, V, M> FullBucket<K, V, M>
652     where M: Deref<Target = RawTable<K, V>> + DerefMut + 't
653 {
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) }
659     }
660 }
661
662 impl<K, V, M> GapThenFull<K, V, M>
663     where M: Deref<Target = RawTable<K, V>>
664 {
665     #[inline]
666     pub fn full(&self) -> &FullBucket<K, V, M> {
667         &self.full
668     }
669
670     pub fn into_bucket(self) -> Bucket<K, V, M> {
671         self.full.into_bucket()
672     }
673
674     pub fn shift(mut self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
675         unsafe {
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);
678         }
679
680         let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
681
682         match self.full.next().peek() {
683             Full(bucket) => {
684                 self.gap.raw = prev_raw;
685                 self.gap.idx = prev_idx;
686
687                 self.full = bucket;
688
689                 Ok(self)
690             }
691             Empty(b) => Err(b.into_bucket()),
692         }
693     }
694 }
695
696
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`.
699 ///
700 /// # Panics
701 ///
702 /// Panics if `target_alignment` is not a power of two.
703 #[inline]
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)
707 }
708
709 #[test]
710 fn test_rounding() {
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);
717 }
718
719 // Returns a tuple of (pairs_offset, end_of_pairs_offset),
720 // from the start of a mallocated array.
721 #[inline]
722 fn calculate_offsets(hashes_size: usize,
723                      pairs_size: usize,
724                      pairs_align: 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);
728
729     (pairs_offset, end_of_pairs, oflo)
730 }
731
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,
735                         hash_align: usize,
736                         pairs_size: usize,
737                         pairs_align: usize)
738                         -> (usize, usize, usize, bool) {
739     let hash_offset = 0;
740     let (_, end_of_pairs, oflo) = calculate_offsets(hash_size, pairs_size, pairs_align);
741
742     let align = cmp::max(hash_align, pairs_align);
743
744     (align, hash_offset, end_of_pairs, oflo)
745 }
746
747 #[test]
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));
755 }
756
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> {
761         if capacity == 0 {
762             return RawTable {
763                 size: 0,
764                 capacity: 0,
765                 hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint),
766                 marker: marker::PhantomData,
767             };
768         }
769
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)>());
774
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
778         // point into it.
779         //
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>(),
785                                                                         pairs_size,
786                                                                         align_of::<(K, V)>());
787         assert!(!oflo, "capacity overflow");
788
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();
791         assert!(size >=
792                 capacity.checked_mul(size_of_bucket)
793                     .expect("capacity overflow"),
794                 "capacity overflow");
795
796         let buffer = allocate(size, alignment);
797         if buffer.is_null() {
798             ::alloc::oom()
799         }
800
801         let hashes = buffer.offset(hash_offset as isize) as *mut HashUint;
802
803         RawTable {
804             capacity: capacity,
805             size: 0,
806             hashes: TaggedHashUintPtr::new(hashes),
807             marker: marker::PhantomData,
808         }
809     }
810
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)>();
814
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");
819         unsafe {
820             RawBucket {
821                 hash: self.hashes.ptr(),
822                 pair: buffer.offset(pairs_offset as isize) as *const _,
823                 _marker: marker::PhantomData,
824             }
825         }
826     }
827
828     /// Creates a new raw table from a given capacity. All buckets are
829     /// initially empty.
830     pub fn new(capacity: usize) -> RawTable<K, V> {
831         unsafe {
832             let ret = RawTable::new_uninitialized(capacity);
833             ptr::write_bytes(ret.hashes.ptr(), 0, capacity);
834             ret
835         }
836     }
837
838     /// The hashtable's capacity, similar to a vector's.
839     pub fn capacity(&self) -> usize {
840         self.capacity
841     }
842
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 {
846         self.size
847     }
848
849     fn raw_buckets(&self) -> RawBuckets<K, V> {
850         RawBuckets {
851             raw: self.first_bucket_raw(),
852             hashes_end: unsafe { self.hashes.ptr().offset(self.capacity as isize) },
853             marker: marker::PhantomData,
854         }
855     }
856
857     pub fn iter(&self) -> Iter<K, V> {
858         Iter {
859             iter: self.raw_buckets(),
860             elems_left: self.size(),
861         }
862     }
863
864     pub fn iter_mut(&mut self) -> IterMut<K, V> {
865         IterMut {
866             iter: self.raw_buckets(),
867             elems_left: self.size(),
868             _marker: marker::PhantomData,
869         }
870     }
871
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.
875         IntoIter {
876             iter: RawBuckets {
877                 raw: raw,
878                 hashes_end: hashes_end,
879                 marker: marker::PhantomData,
880             },
881             table: self,
882         }
883     }
884
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.
888         Drain {
889             iter: RawBuckets {
890                 raw: raw,
891                 hashes_end: hashes_end,
892                 marker: marker::PhantomData,
893             },
894             table: unsafe { Shared::new(self) },
895             marker: marker::PhantomData,
896         }
897     }
898
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();
903         RevMoveBuckets {
904             raw: raw_bucket.offset(self.capacity as isize),
905             hashes_end: raw_bucket.hash,
906             elems_left: self.size,
907             marker: marker::PhantomData,
908         }
909     }
910
911     /// Set the table tag
912     pub fn set_tag(&mut self, value: bool) {
913         self.hashes.set_tag(value)
914     }
915
916     /// Get the table tag
917     pub fn tag(&self) -> bool {
918         self.hashes.tag()
919     }
920 }
921
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,
927
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
932     // anyway.
933     marker: marker::PhantomData<&'a ()>,
934 }
935
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> {
939         RawBuckets {
940             raw: self.raw,
941             hashes_end: self.hashes_end,
942             marker: marker::PhantomData,
943         }
944     }
945 }
946
947
948 impl<'a, K, V> Iterator for RawBuckets<'a, K, V> {
949     type Item = RawBucket<K, V>;
950
951     fn next(&mut self) -> Option<RawBucket<K, V>> {
952         while self.raw.hash != self.hashes_end {
953             unsafe {
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 {
958                     return Some(prev);
959                 }
960             }
961         }
962
963         None
964     }
965 }
966
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,
973     elems_left: usize,
974
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
977     // type.
978     marker: marker::PhantomData<&'a ()>,
979 }
980
981 impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
982     type Item = (K, V);
983
984     fn next(&mut self) -> Option<(K, V)> {
985         if self.elems_left == 0 {
986             return None;
987         }
988
989         loop {
990             debug_assert!(self.raw.hash != self.hashes_end);
991
992             unsafe {
993                 self.raw = self.raw.offset(-1);
994
995                 if *self.raw.hash != EMPTY_BUCKET {
996                     self.elems_left -= 1;
997                     return Some(ptr::read(self.raw.pair));
998                 }
999             }
1000         }
1001     }
1002 }
1003
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>,
1007     elems_left: usize,
1008 }
1009
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> {}
1012
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> {
1016         Iter {
1017             iter: self.iter.clone(),
1018             elems_left: self.elems_left,
1019         }
1020     }
1021 }
1022
1023
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>,
1027     elems_left: usize,
1028     // To ensure invariance with respect to V
1029     _marker: marker::PhantomData<&'a mut V>,
1030 }
1031
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> {}
1036
1037 impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> {
1038     pub fn iter(&self) -> Iter<K, V> {
1039         Iter {
1040             iter: self.iter.clone(),
1041             elems_left: self.elems_left,
1042         }
1043     }
1044 }
1045
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>,
1050 }
1051
1052 unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {}
1053 unsafe impl<K: Send, V: Send> Send for IntoIter<K, V> {}
1054
1055 impl<K, V> IntoIter<K, V> {
1056     pub fn iter(&self) -> Iter<K, V> {
1057         Iter {
1058             iter: self.iter.clone(),
1059             elems_left: self.table.size,
1060         }
1061     }
1062 }
1063
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>>,
1069 }
1070
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> {}
1073
1074 impl<'a, K, V> Drain<'a, K, V> {
1075     pub fn iter(&self) -> Iter<K, V> {
1076         unsafe {
1077             Iter {
1078                 iter: self.iter.clone(),
1079                 elems_left: (**self.table).size,
1080             }
1081         }
1082     }
1083 }
1084
1085 impl<'a, K, V> Iterator for Iter<'a, K, V> {
1086     type Item = (&'a K, &'a V);
1087
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) }
1092         })
1093     }
1094
1095     fn size_hint(&self) -> (usize, Option<usize>) {
1096         (self.elems_left, Some(self.elems_left))
1097     }
1098 }
1099 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
1100     fn len(&self) -> usize {
1101         self.elems_left
1102     }
1103 }
1104
1105 impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1106     type Item = (&'a K, &'a mut V);
1107
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) }
1113         })
1114     }
1115
1116     fn size_hint(&self) -> (usize, Option<usize>) {
1117         (self.elems_left, Some(self.elems_left))
1118     }
1119 }
1120 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
1121     fn len(&self) -> usize {
1122         self.elems_left
1123     }
1124 }
1125
1126 impl<K, V> Iterator for IntoIter<K, V> {
1127     type Item = (SafeHash, K, V);
1128
1129     fn next(&mut self) -> Option<(SafeHash, K, V)> {
1130         self.iter.next().map(|bucket| {
1131             self.table.size -= 1;
1132             unsafe {
1133                 let (k, v) = ptr::read(bucket.pair);
1134                 (SafeHash { hash: *bucket.hash }, k, v)
1135             }
1136         })
1137     }
1138
1139     fn size_hint(&self) -> (usize, Option<usize>) {
1140         let size = self.table.size();
1141         (size, Some(size))
1142     }
1143 }
1144 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
1145     fn len(&self) -> usize {
1146         self.table.size()
1147     }
1148 }
1149
1150 impl<'a, K, V> Iterator for Drain<'a, K, V> {
1151     type Item = (SafeHash, K, V);
1152
1153     #[inline]
1154     fn next(&mut self) -> Option<(SafeHash, K, V)> {
1155         self.iter.next().map(|bucket| {
1156             unsafe {
1157                 (**self.table).size -= 1;
1158                 let (k, v) = ptr::read(bucket.pair);
1159                 (SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) }, k, v)
1160             }
1161         })
1162     }
1163
1164     fn size_hint(&self) -> (usize, Option<usize>) {
1165         let size = unsafe { (**self.table).size() };
1166         (size, Some(size))
1167     }
1168 }
1169 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
1170     fn len(&self) -> usize {
1171         unsafe { (**self.table).size() }
1172     }
1173 }
1174
1175 impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
1176     fn drop(&mut self) {
1177         for _ in self {}
1178     }
1179 }
1180
1181 impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
1182     fn clone(&self) -> RawTable<K, V> {
1183         unsafe {
1184             let mut new_ht = RawTable::new_uninitialized(self.capacity());
1185
1186             {
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() {
1192                         Full(full) => {
1193                             let (h, k, v) = {
1194                                 let (k, v) = full.read();
1195                                 (full.hash(), k.clone(), v.clone())
1196                             };
1197                             *new_buckets.raw.hash = h.inspect();
1198                             ptr::write(new_buckets.raw.pair as *mut (K, V), (k, v));
1199                         }
1200                         Empty(..) => {
1201                             *new_buckets.raw.hash = EMPTY_BUCKET;
1202                         }
1203                     }
1204                     new_buckets.next();
1205                     buckets.next();
1206                 }
1207             };
1208
1209             new_ht.size = self.size();
1210
1211             new_ht
1212         }
1213     }
1214 }
1215
1216 unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
1217     fn drop(&mut self) {
1218         if self.capacity == 0 {
1219             return;
1220         }
1221
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.
1227         unsafe {
1228             if needs_drop::<(K, V)>() {
1229                 // avoid linear runtime for types that don't need drop
1230                 for _ in self.rev_move_buckets() {}
1231             }
1232         }
1233
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>(),
1238                                                           pairs_size,
1239                                                           align_of::<(K, V)>());
1240
1241         debug_assert!(!oflo, "should be impossible");
1242
1243         unsafe {
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.
1247         }
1248     }
1249 }