]> git.lizzy.rs Git - rust.git/blob - src/libstd/collections/hash/map.rs
std: Add a new top-level thread_local module
[rust.git] / src / libstd / collections / hash / map.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 //
11 // ignore-lexer-test FIXME #15883
12
13 pub use self::Entry::*;
14 use self::SearchResult::*;
15 use self::VacantEntryState::*;
16
17 use borrow::BorrowFrom;
18 use clone::Clone;
19 use cmp::{max, Eq, Equiv, PartialEq};
20 use default::Default;
21 use fmt::{mod, Show};
22 use hash::{Hash, Hasher, RandomSipHasher};
23 use iter::{mod, Iterator, FromIterator, Extend};
24 use kinds::Sized;
25 use mem::{mod, replace};
26 use num::UnsignedInt;
27 use ops::{Deref, Index, IndexMut};
28 use option::{Some, None, Option};
29 use result::{Result, Ok, Err};
30
31 use super::table;
32 use super::table::{
33     Bucket,
34     Empty,
35     EmptyBucket,
36     Full,
37     FullBucket,
38     FullBucketImm,
39     FullBucketMut,
40     RawTable,
41     SafeHash
42 };
43
44 // FIXME(conventions): update capacity management to match other collections (no auto-shrink)
45
46 const INITIAL_LOG2_CAP: uint = 5;
47 pub const INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5
48
49 /// The default behavior of HashMap implements a load factor of 90.9%.
50 /// This behavior is characterized by the following conditions:
51 ///
52 /// - if size > 0.909 * capacity: grow
53 /// - if size < 0.25 * capacity: shrink (if this won't bring capacity lower
54 ///   than the minimum)
55 #[deriving(Clone)]
56 struct DefaultResizePolicy {
57     /// Doubled minimal capacity. The capacity must never drop below
58     /// the minimum capacity. (The check happens before the capacity
59     /// is potentially halved.)
60     minimum_capacity2: uint
61 }
62
63 impl DefaultResizePolicy {
64     fn new(new_capacity: uint) -> DefaultResizePolicy {
65         DefaultResizePolicy {
66             minimum_capacity2: new_capacity << 1
67         }
68     }
69
70     #[inline]
71     fn capacity_range(&self, new_size: uint) -> (uint, uint) {
72         // Here, we are rephrasing the logic by specifying the ranges:
73         //
74         // - if `size * 1.1 < cap < size * 4`: don't resize
75         // - if `cap < minimum_capacity * 2`: don't shrink
76         // - otherwise, resize accordingly
77         ((new_size * 11) / 10, max(new_size << 2, self.minimum_capacity2))
78     }
79
80     #[inline]
81     fn reserve(&mut self, new_capacity: uint) {
82         self.minimum_capacity2 = new_capacity << 1;
83     }
84 }
85
86 // The main performance trick in this hashmap is called Robin Hood Hashing.
87 // It gains its excellent performance from one essential operation:
88 //
89 //    If an insertion collides with an existing element, and that element's
90 //    "probe distance" (how far away the element is from its ideal location)
91 //    is higher than how far we've already probed, swap the elements.
92 //
93 // This massively lowers variance in probe distance, and allows us to get very
94 // high load factors with good performance. The 90% load factor I use is rather
95 // conservative.
96 //
97 // > Why a load factor of approximately 90%?
98 //
99 // In general, all the distances to initial buckets will converge on the mean.
100 // At a load factor of α, the odds of finding the target bucket after k
101 // probes is approximately 1-α^k. If we set this equal to 50% (since we converge
102 // on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round
103 // this down to make the math easier on the CPU and avoid its FPU.
104 // Since on average we start the probing in the middle of a cache line, this
105 // strategy pulls in two cache lines of hashes on every lookup. I think that's
106 // pretty good, but if you want to trade off some space, it could go down to one
107 // cache line on average with an α of 0.84.
108 //
109 // > Wait, what? Where did you get 1-α^k from?
110 //
111 // On the first probe, your odds of a collision with an existing element is α.
112 // The odds of doing this twice in a row is approximately α^2. For three times,
113 // α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT
114 // colliding after k tries is 1-α^k.
115 //
116 // The paper from 1986 cited below mentions an implementation which keeps track
117 // of the distance-to-initial-bucket histogram. This approach is not suitable
118 // for modern architectures because it requires maintaining an internal data
119 // structure. This allows very good first guesses, but we are most concerned
120 // with guessing entire cache lines, not individual indexes. Furthermore, array
121 // accesses are no longer linear and in one direction, as we have now. There
122 // is also memory and cache pressure that this would entail that would be very
123 // difficult to properly see in a microbenchmark.
124 //
125 // ## Future Improvements (FIXME!)
126 //
127 // Allow the load factor to be changed dynamically and/or at initialization.
128 //
129 // Also, would it be possible for us to reuse storage when growing the
130 // underlying table? This is exactly the use case for 'realloc', and may
131 // be worth exploring.
132 //
133 // ## Future Optimizations (FIXME!)
134 //
135 // Another possible design choice that I made without any real reason is
136 // parameterizing the raw table over keys and values. Technically, all we need
137 // is the size and alignment of keys and values, and the code should be just as
138 // efficient (well, we might need one for power-of-two size and one for not...).
139 // This has the potential to reduce code bloat in rust executables, without
140 // really losing anything except 4 words (key size, key alignment, val size,
141 // val alignment) which can be passed in to every call of a `RawTable` function.
142 // This would definitely be an avenue worth exploring if people start complaining
143 // about the size of rust executables.
144 //
145 // Annotate exceedingly likely branches in `table::make_hash`
146 // and `search_hashed` to reduce instruction cache pressure
147 // and mispredictions once it becomes possible (blocked on issue #11092).
148 //
149 // Shrinking the table could simply reallocate in place after moving buckets
150 // to the first half.
151 //
152 // The growth algorithm (fragment of the Proof of Correctness)
153 // --------------------
154 //
155 // The growth algorithm is basically a fast path of the naive reinsertion-
156 // during-resize algorithm. Other paths should never be taken.
157 //
158 // Consider growing a robin hood hashtable of capacity n. Normally, we do this
159 // by allocating a new table of capacity `2n`, and then individually reinsert
160 // each element in the old table into the new one. This guarantees that the
161 // new table is a valid robin hood hashtable with all the desired statistical
162 // properties. Remark that the order we reinsert the elements in should not
163 // matter. For simplicity and efficiency, we will consider only linear
164 // reinsertions, which consist of reinserting all elements in the old table
165 // into the new one by increasing order of index. However we will not be
166 // starting our reinsertions from index 0 in general. If we start from index
167 // i, for the purpose of reinsertion we will consider all elements with real
168 // index j < i to have virtual index n + j.
169 //
170 // Our hash generation scheme consists of generating a 64-bit hash and
171 // truncating the most significant bits. When moving to the new table, we
172 // simply introduce a new bit to the front of the hash. Therefore, if an
173 // elements has ideal index i in the old table, it can have one of two ideal
174 // locations in the new table. If the new bit is 0, then the new ideal index
175 // is i. If the new bit is 1, then the new ideal index is n + i. Intutively,
176 // we are producing two independent tables of size n, and for each element we
177 // independently choose which table to insert it into with equal probability.
178 // However the rather than wrapping around themselves on overflowing their
179 // indexes, the first table overflows into the first, and the first into the
180 // second. Visually, our new table will look something like:
181 //
182 // [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy]
183 //
184 // Where x's are elements inserted into the first table, y's are elements
185 // inserted into the second, and _'s are empty sections. We now define a few
186 // key concepts that we will use later. Note that this is a very abstract
187 // perspective of the table. A real resized table would be at least half
188 // empty.
189 //
190 // Theorem: A linear robin hood reinsertion from the first ideal element
191 // produces identical results to a linear naive reinsertion from the same
192 // element.
193 //
194 // FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs
195
196 /// A hash map implementation which uses linear probing with Robin
197 /// Hood bucket stealing.
198 ///
199 /// The hashes are all keyed by the task-local random number generator
200 /// on creation by default. This means that the ordering of the keys is
201 /// randomized, but makes the tables more resistant to
202 /// denial-of-service attacks (Hash DoS). This behaviour can be
203 /// overridden with one of the constructors.
204 ///
205 /// It is required that the keys implement the `Eq` and `Hash` traits, although
206 /// this can frequently be achieved by using `#[deriving(Eq, Hash)]`.
207 ///
208 /// Relevant papers/articles:
209 ///
210 /// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf)
211 /// 2. Emmanuel Goossaert. ["Robin Hood
212 ///    hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/)
213 /// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift
214 ///    deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/)
215 ///
216 /// # Example
217 ///
218 /// ```
219 /// use std::collections::HashMap;
220 ///
221 /// // type inference lets us omit an explicit type signature (which
222 /// // would be `HashMap<&str, &str>` in this example).
223 /// let mut book_reviews = HashMap::new();
224 ///
225 /// // review some books.
226 /// book_reviews.insert("Adventures of Huckleberry Finn",    "My favorite book.");
227 /// book_reviews.insert("Grimms' Fairy Tales",               "Masterpiece.");
228 /// book_reviews.insert("Pride and Prejudice",               "Very enjoyable.");
229 /// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.");
230 ///
231 /// // check for a specific one.
232 /// if !book_reviews.contains_key(&("Les Misérables")) {
233 ///     println!("We've got {} reviews, but Les Misérables ain't one.",
234 ///              book_reviews.len());
235 /// }
236 ///
237 /// // oops, this review has a lot of spelling mistakes, let's delete it.
238 /// book_reviews.remove(&("The Adventures of Sherlock Holmes"));
239 ///
240 /// // look up the values associated with some keys.
241 /// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
242 /// for book in to_find.iter() {
243 ///     match book_reviews.get(book) {
244 ///         Some(review) => println!("{}: {}", *book, *review),
245 ///         None => println!("{} is unreviewed.", *book)
246 ///     }
247 /// }
248 ///
249 /// // iterate over everything.
250 /// for (book, review) in book_reviews.iter() {
251 ///     println!("{}: \"{}\"", *book, *review);
252 /// }
253 /// ```
254 ///
255 /// The easiest way to use `HashMap` with a custom type is to derive `Eq` and `Hash`.
256 /// We must also derive `PartialEq`.
257 ///
258 /// ```
259 /// use std::collections::HashMap;
260 ///
261 /// #[deriving(Hash, Eq, PartialEq, Show)]
262 /// struct Viking<'a> {
263 ///     name: &'a str,
264 ///     power: uint,
265 /// }
266 ///
267 /// let mut vikings = HashMap::new();
268 ///
269 /// vikings.insert("Norway", Viking { name: "Einar", power: 9u });
270 /// vikings.insert("Denmark", Viking { name: "Olaf", power: 4u });
271 /// vikings.insert("Iceland", Viking { name: "Harald", power: 8u });
272 ///
273 /// // Use derived implementation to print the vikings.
274 /// for (land, viking) in vikings.iter() {
275 ///     println!("{} at {}", viking, land);
276 /// }
277 /// ```
278 #[deriving(Clone)]
279 pub struct HashMap<K, V, H = RandomSipHasher> {
280     // All hashes are keyed on these values, to prevent hash collision attacks.
281     hasher: H,
282
283     table: RawTable<K, V>,
284
285     // We keep this at the end since it might as well have tail padding.
286     resize_policy: DefaultResizePolicy,
287 }
288
289 /// Search for a pre-hashed key.
290 fn search_hashed<K, V, M: Deref<RawTable<K, V>>>(table: M,
291                                                  hash: &SafeHash,
292                                                  is_match: |&K| -> bool)
293                                                  -> SearchResult<K, V, M> {
294     let size = table.size();
295     let mut probe = Bucket::new(table, hash);
296     let ib = probe.index();
297
298     while probe.index() != ib + size {
299         let full = match probe.peek() {
300             Empty(b) => return TableRef(b.into_table()), // hit an empty bucket
301             Full(b) => b
302         };
303
304         if full.distance() + ib < full.index() {
305             // We can finish the search early if we hit any bucket
306             // with a lower distance to initial bucket than we've probed.
307             return TableRef(full.into_table());
308         }
309
310         // If the hash doesn't match, it can't be this one..
311         if *hash == full.hash() {
312             let matched = {
313                 let (k, _) = full.read();
314                 is_match(k)
315             };
316
317             // If the key doesn't match, it can't be this one..
318             if matched {
319                 return FoundExisting(full);
320             }
321         }
322
323         probe = full.next();
324     }
325
326     TableRef(probe.into_table())
327 }
328
329 fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
330     let (empty, retkey, retval) = starting_bucket.take();
331     let mut gap = match empty.gap_peek() {
332         Some(b) => b,
333         None => return (retkey, retval)
334     };
335
336     while gap.full().distance() != 0 {
337         gap = match gap.shift() {
338             Some(b) => b,
339             None => break
340         };
341     }
342
343     // Now we've done all our shifting. Return the value we grabbed earlier.
344     return (retkey, retval);
345 }
346
347 /// Perform robin hood bucket stealing at the given `bucket`. You must
348 /// also pass the position of that bucket's initial bucket so we don't have
349 /// to recalculate it.
350 ///
351 /// `hash`, `k`, and `v` are the elements to "robin hood" into the hashtable.
352 fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
353                         mut ib: uint,
354                         mut hash: SafeHash,
355                         mut k: K,
356                         mut v: V)
357                         -> &'a mut V {
358     let starting_index = bucket.index();
359     let size = {
360         let table = bucket.table(); // FIXME "lifetime too short".
361         table.size()
362     };
363     // There can be at most `size - dib` buckets to displace, because
364     // in the worst case, there are `size` elements and we already are
365     // `distance` buckets away from the initial one.
366     let idx_end = starting_index + size - bucket.distance();
367
368     loop {
369         let (old_hash, old_key, old_val) = bucket.replace(hash, k, v);
370         loop {
371             let probe = bucket.next();
372             assert!(probe.index() != idx_end);
373
374             let full_bucket = match probe.peek() {
375                 table::Empty(bucket) => {
376                     // Found a hole!
377                     let b = bucket.put(old_hash, old_key, old_val);
378                     // Now that it's stolen, just read the value's pointer
379                     // right out of the table!
380                     let (_, v) = Bucket::at_index(b.into_table(), starting_index).peek()
381                                                                                  .expect_full()
382                                                                                  .into_mut_refs();
383                     return v;
384                 },
385                 table::Full(bucket) => bucket
386             };
387
388             let probe_ib = full_bucket.index() - full_bucket.distance();
389
390             bucket = full_bucket;
391
392             // Robin hood! Steal the spot.
393             if ib < probe_ib {
394                 ib = probe_ib;
395                 hash = old_hash;
396                 k = old_key;
397                 v = old_val;
398                 break;
399             }
400         }
401     }
402 }
403
404 /// A result that works like Option<FullBucket<..>> but preserves
405 /// the reference that grants us access to the table in any case.
406 enum SearchResult<K, V, M> {
407     // This is an entry that holds the given key:
408     FoundExisting(FullBucket<K, V, M>),
409
410     // There was no such entry. The reference is given back:
411     TableRef(M)
412 }
413
414 impl<K, V, M> SearchResult<K, V, M> {
415     fn into_option(self) -> Option<FullBucket<K, V, M>> {
416         match self {
417             FoundExisting(bucket) => Some(bucket),
418             TableRef(_) => None
419         }
420     }
421 }
422
423 impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
424     fn make_hash<Sized? X: Hash<S>>(&self, x: &X) -> SafeHash {
425         table::make_hash(&self.hasher, x)
426     }
427
428     fn search_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, q: &Q)
429                     -> Option<FullBucketImm<'a, K, V>> {
430         let hash = self.make_hash(q);
431         search_hashed(&self.table, &hash, |k| q.equiv(k)).into_option()
432     }
433
434     fn search_equiv_mut<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a mut self, q: &Q)
435                     -> Option<FullBucketMut<'a, K, V>> {
436         let hash = self.make_hash(q);
437         search_hashed(&mut self.table, &hash, |k| q.equiv(k)).into_option()
438     }
439
440     /// Search for a key, yielding the index if it's found in the hashtable.
441     /// If you already have the hash for the key lying around, use
442     /// search_hashed.
443     fn search<'a, Sized? Q>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
444         where Q: BorrowFrom<K> + Eq + Hash<S>
445     {
446         let hash = self.make_hash(q);
447         search_hashed(&self.table, &hash, |k| q.eq(BorrowFrom::borrow_from(k)))
448             .into_option()
449     }
450
451     fn search_mut<'a, Sized? Q>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
452         where Q: BorrowFrom<K> + Eq + Hash<S>
453     {
454         let hash = self.make_hash(q);
455         search_hashed(&mut self.table, &hash, |k| q.eq(BorrowFrom::borrow_from(k)))
456             .into_option()
457     }
458
459     // The caller should ensure that invariants by Robin Hood Hashing hold.
460     fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
461         let cap = self.table.capacity();
462         let mut buckets = Bucket::new(&mut self.table, &hash);
463         let ib = buckets.index();
464
465         while buckets.index() != ib + cap {
466             // We don't need to compare hashes for value swap.
467             // Not even DIBs for Robin Hood.
468             buckets = match buckets.peek() {
469                 Empty(empty) => {
470                     empty.put(hash, k, v);
471                     return;
472                 }
473                 Full(b) => b.into_bucket()
474             };
475             buckets.next();
476         }
477         panic!("Internal HashMap error: Out of space.");
478     }
479 }
480
481 impl<K: Hash + Eq, V> HashMap<K, V, RandomSipHasher> {
482     /// Create an empty HashMap.
483     ///
484     /// # Example
485     ///
486     /// ```
487     /// use std::collections::HashMap;
488     /// let mut map: HashMap<&str, int> = HashMap::new();
489     /// ```
490     #[inline]
491     #[unstable = "matches collection reform specification, waiting for dust to settle"]
492     pub fn new() -> HashMap<K, V, RandomSipHasher> {
493         let hasher = RandomSipHasher::new();
494         HashMap::with_hasher(hasher)
495     }
496
497     /// Creates an empty hash map with the given initial capacity.
498     ///
499     /// # Example
500     ///
501     /// ```
502     /// use std::collections::HashMap;
503     /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
504     /// ```
505     #[inline]
506     #[unstable = "matches collection reform specification, waiting for dust to settle"]
507     pub fn with_capacity(capacity: uint) -> HashMap<K, V, RandomSipHasher> {
508         let hasher = RandomSipHasher::new();
509         HashMap::with_capacity_and_hasher(capacity, hasher)
510     }
511 }
512
513 impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
514     /// Creates an empty hashmap which will use the given hasher to hash keys.
515     ///
516     /// The creates map has the default initial capacity.
517     ///
518     /// # Example
519     ///
520     /// ```
521     /// use std::collections::HashMap;
522     /// use std::hash::sip::SipHasher;
523     ///
524     /// let h = SipHasher::new();
525     /// let mut map = HashMap::with_hasher(h);
526     /// map.insert(1i, 2u);
527     /// ```
528     #[inline]
529     pub fn with_hasher(hasher: H) -> HashMap<K, V, H> {
530         HashMap {
531             hasher:        hasher,
532             resize_policy: DefaultResizePolicy::new(INITIAL_CAPACITY),
533             table:         RawTable::new(0),
534         }
535     }
536
537     /// Create an empty HashMap with space for at least `capacity`
538     /// elements, using `hasher` to hash the keys.
539     ///
540     /// Warning: `hasher` is normally randomly generated, and
541     /// is designed to allow HashMaps to be resistant to attacks that
542     /// cause many collisions and very poor performance. Setting it
543     /// manually using this function can expose a DoS attack vector.
544     ///
545     /// # Example
546     ///
547     /// ```
548     /// use std::collections::HashMap;
549     /// use std::hash::sip::SipHasher;
550     ///
551     /// let h = SipHasher::new();
552     /// let mut map = HashMap::with_capacity_and_hasher(10, h);
553     /// map.insert(1i, 2u);
554     /// ```
555     #[inline]
556     pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap<K, V, H> {
557         let cap = max(INITIAL_CAPACITY, capacity).next_power_of_two();
558         HashMap {
559             hasher:        hasher,
560             resize_policy: DefaultResizePolicy::new(cap),
561             table:         RawTable::new(cap),
562         }
563     }
564
565     /// The hashtable will never try to shrink below this size. You can use
566     /// this function to reduce reallocations if your hashtable frequently
567     /// grows and shrinks by large amounts.
568     ///
569     /// This function has no effect on the operational semantics of the
570     /// hashtable, only on performance.
571     ///
572     /// # Example
573     ///
574     /// ```
575     /// use std::collections::HashMap;
576     /// let mut map: HashMap<&str, int> = HashMap::new();
577     /// map.reserve(10);
578     /// ```
579     pub fn reserve(&mut self, new_minimum_capacity: uint) {
580         let cap = max(INITIAL_CAPACITY, new_minimum_capacity).next_power_of_two();
581
582         self.resize_policy.reserve(cap);
583
584         if self.table.capacity() < cap {
585             self.resize(cap);
586         }
587     }
588
589     /// Resizes the internal vectors to a new capacity. It's your responsibility to:
590     ///   1) Make sure the new capacity is enough for all the elements, accounting
591     ///      for the load factor.
592     ///   2) Ensure new_capacity is a power of two.
593     fn resize(&mut self, new_capacity: uint) {
594         assert!(self.table.size() <= new_capacity);
595         assert!(new_capacity.is_power_of_two());
596
597         let mut old_table = replace(&mut self.table, RawTable::new(new_capacity));
598         let old_size = old_table.size();
599
600         if old_table.capacity() == 0 || old_table.size() == 0 {
601             return;
602         }
603
604         if new_capacity < old_table.capacity() {
605             // Shrink the table. Naive algorithm for resizing:
606             for (h, k, v) in old_table.into_iter() {
607                 self.insert_hashed_nocheck(h, k, v);
608             }
609         } else {
610             // Grow the table.
611             // Specialization of the other branch.
612             let mut bucket = Bucket::first(&mut old_table);
613
614             // "So a few of the first shall be last: for many be called,
615             // but few chosen."
616             //
617             // We'll most likely encounter a few buckets at the beginning that
618             // have their initial buckets near the end of the table. They were
619             // placed at the beginning as the probe wrapped around the table
620             // during insertion. We must skip forward to a bucket that won't
621             // get reinserted too early and won't unfairly steal others spot.
622             // This eliminates the need for robin hood.
623             loop {
624                 bucket = match bucket.peek() {
625                     Full(full) => {
626                         if full.distance() == 0 {
627                             // This bucket occupies its ideal spot.
628                             // It indicates the start of another "cluster".
629                             bucket = full.into_bucket();
630                             break;
631                         }
632                         // Leaving this bucket in the last cluster for later.
633                         full.into_bucket()
634                     }
635                     Empty(b) => {
636                         // Encountered a hole between clusters.
637                         b.into_bucket()
638                     }
639                 };
640                 bucket.next();
641             }
642
643             // This is how the buckets might be laid out in memory:
644             // ($ marks an initialized bucket)
645             //  ________________
646             // |$$$_$$$$$$_$$$$$|
647             //
648             // But we've skipped the entire initial cluster of buckets
649             // and will continue iteration in this order:
650             //  ________________
651             //     |$$$$$$_$$$$$
652             //                  ^ wrap around once end is reached
653             //  ________________
654             //  $$$_____________|
655             //    ^ exit once table.size == 0
656             loop {
657                 bucket = match bucket.peek() {
658                     Full(bucket) => {
659                         let h = bucket.hash();
660                         let (b, k, v) = bucket.take();
661                         self.insert_hashed_ordered(h, k, v);
662                         {
663                             let t = b.table(); // FIXME "lifetime too short".
664                             if t.size() == 0 { break }
665                         };
666                         b.into_bucket()
667                     }
668                     Empty(b) => b.into_bucket()
669                 };
670                 bucket.next();
671             }
672         }
673
674         assert_eq!(self.table.size(), old_size);
675     }
676
677     /// Performs any necessary resize operations, such that there's space for
678     /// new_size elements.
679     fn make_some_room(&mut self, new_size: uint) {
680         let (grow_at, shrink_at) = self.resize_policy.capacity_range(new_size);
681         let cap = self.table.capacity();
682
683         // An invalid value shouldn't make us run out of space.
684         debug_assert!(grow_at >= new_size);
685
686         if cap <= grow_at {
687             let new_capacity = max(cap << 1, INITIAL_CAPACITY);
688             self.resize(new_capacity);
689         } else if shrink_at <= cap {
690             let new_capacity = cap >> 1;
691             self.resize(new_capacity);
692         }
693     }
694
695     /// Insert a pre-hashed key-value pair, without first checking
696     /// that there's enough room in the buckets. Returns a reference to the
697     /// newly insert value.
698     ///
699     /// If the key already exists, the hashtable will be returned untouched
700     /// and a reference to the existing element will be returned.
701     fn insert_hashed_nocheck(&mut self, hash: SafeHash, k: K, v: V) -> &mut V {
702         self.insert_or_replace_with(hash, k, v, |_, _, _| ())
703     }
704
705     fn insert_or_replace_with<'a>(&'a mut self,
706                                   hash: SafeHash,
707                                   k: K,
708                                   v: V,
709                                   found_existing: |&mut K, &mut V, V|)
710                                   -> &'a mut V {
711         // Worst case, we'll find one empty bucket among `size + 1` buckets.
712         let size = self.table.size();
713         let mut probe = Bucket::new(&mut self.table, &hash);
714         let ib = probe.index();
715
716         loop {
717             let mut bucket = match probe.peek() {
718                 Empty(bucket) => {
719                     // Found a hole!
720                     let bucket = bucket.put(hash, k, v);
721                     let (_, val) = bucket.into_mut_refs();
722                     return val;
723                 },
724                 Full(bucket) => bucket
725             };
726
727             if bucket.hash() == hash {
728                 let found_match = {
729                     let (bucket_k, _) = bucket.read_mut();
730                     k == *bucket_k
731                 };
732                 if found_match {
733                     let (bucket_k, bucket_v) = bucket.into_mut_refs();
734                     debug_assert!(k == *bucket_k);
735                     // Key already exists. Get its reference.
736                     found_existing(bucket_k, bucket_v, v);
737                     return bucket_v;
738                 }
739             }
740
741             let robin_ib = bucket.index() as int - bucket.distance() as int;
742
743             if (ib as int) < robin_ib {
744                 // Found a luckier bucket than me. Better steal his spot.
745                 return robin_hood(bucket, robin_ib as uint, hash, k, v);
746             }
747
748             probe = bucket.next();
749             assert!(probe.index() != ib + size + 1);
750         }
751     }
752
753     /// Deprecated: use `contains_key` and `BorrowFrom` instead.
754     #[deprecated = "use contains_key and BorrowFrom instead"]
755     pub fn contains_key_equiv<Sized? Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
756         self.search_equiv(key).is_some()
757     }
758
759     /// Deprecated: use `get` and `BorrowFrom` instead.
760     #[deprecated = "use get and BorrowFrom instead"]
761     pub fn find_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
762         match self.search_equiv(k) {
763             None      => None,
764             Some(bucket) => {
765                 let (_, v_ref) = bucket.into_refs();
766                 Some(v_ref)
767             }
768         }
769     }
770
771     /// Deprecated: use `remove` and `BorrowFrom` instead.
772     #[deprecated = "use remove and BorrowFrom instead"]
773     pub fn pop_equiv<Sized? Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
774         if self.table.size() == 0 {
775             return None
776         }
777
778         let potential_new_size = self.table.size() - 1;
779         self.make_some_room(potential_new_size);
780
781         match self.search_equiv_mut(k) {
782             Some(bucket) => {
783                 let (_k, val) = pop_internal(bucket);
784                 Some(val)
785             }
786             _ => None
787         }
788     }
789
790     /// An iterator visiting all keys in arbitrary order.
791     /// Iterator element type is `&'a K`.
792     ///
793     /// # Example
794     ///
795     /// ```
796     /// use std::collections::HashMap;
797     ///
798     /// let mut map = HashMap::new();
799     /// map.insert("a", 1i);
800     /// map.insert("b", 2);
801     /// map.insert("c", 3);
802     ///
803     /// for key in map.keys() {
804     ///     println!("{}", key);
805     /// }
806     /// ```
807     #[unstable = "matches collection reform specification, waiting for dust to settle"]
808     pub fn keys(&self) -> Keys<K, V> {
809         self.iter().map(|(k, _v)| k)
810     }
811
812     /// An iterator visiting all values in arbitrary order.
813     /// Iterator element type is `&'a V`.
814     ///
815     /// # Example
816     ///
817     /// ```
818     /// use std::collections::HashMap;
819     ///
820     /// let mut map = HashMap::new();
821     /// map.insert("a", 1i);
822     /// map.insert("b", 2);
823     /// map.insert("c", 3);
824     ///
825     /// for key in map.values() {
826     ///     println!("{}", key);
827     /// }
828     /// ```
829     #[unstable = "matches collection reform specification, waiting for dust to settle"]
830     pub fn values(&self) -> Values<K, V> {
831         self.iter().map(|(_k, v)| v)
832     }
833
834     /// An iterator visiting all key-value pairs in arbitrary order.
835     /// Iterator element type is `(&'a K, &'a V)`.
836     ///
837     /// # Example
838     ///
839     /// ```
840     /// use std::collections::HashMap;
841     ///
842     /// let mut map = HashMap::new();
843     /// map.insert("a", 1i);
844     /// map.insert("b", 2);
845     /// map.insert("c", 3);
846     ///
847     /// for (key, val) in map.iter() {
848     ///     println!("key: {} val: {}", key, val);
849     /// }
850     /// ```
851     #[unstable = "matches collection reform specification, waiting for dust to settle"]
852     pub fn iter(&self) -> Entries<K, V> {
853         Entries { inner: self.table.iter() }
854     }
855
856     /// An iterator visiting all key-value pairs in arbitrary order,
857     /// with mutable references to the values.
858     /// Iterator element type is `(&'a K, &'a mut V)`.
859     ///
860     /// # Example
861     ///
862     /// ```
863     /// use std::collections::HashMap;
864     ///
865     /// let mut map = HashMap::new();
866     /// map.insert("a", 1i);
867     /// map.insert("b", 2);
868     /// map.insert("c", 3);
869     ///
870     /// // Update all values
871     /// for (_, val) in map.iter_mut() {
872     ///     *val *= 2;
873     /// }
874     ///
875     /// for (key, val) in map.iter() {
876     ///     println!("key: {} val: {}", key, val);
877     /// }
878     /// ```
879     #[unstable = "matches collection reform specification, waiting for dust to settle"]
880     pub fn iter_mut(&mut self) -> MutEntries<K, V> {
881         MutEntries { inner: self.table.iter_mut() }
882     }
883
884     /// Creates a consuming iterator, that is, one that moves each key-value
885     /// pair out of the map in arbitrary order. The map cannot be used after
886     /// calling this.
887     ///
888     /// # Example
889     ///
890     /// ```
891     /// use std::collections::HashMap;
892     ///
893     /// let mut map = HashMap::new();
894     /// map.insert("a", 1i);
895     /// map.insert("b", 2);
896     /// map.insert("c", 3);
897     ///
898     /// // Not possible with .iter()
899     /// let vec: Vec<(&str, int)> = map.into_iter().collect();
900     /// ```
901     #[unstable = "matches collection reform specification, waiting for dust to settle"]
902     pub fn into_iter(self) -> MoveEntries<K, V> {
903         MoveEntries {
904             inner: self.table.into_iter().map(|(_, k, v)| (k, v))
905         }
906     }
907
908     /// Gets the given key's corresponding entry in the map for in-place manipulation
909     pub fn entry<'a>(&'a mut self, key: K) -> Entry<'a, K, V> {
910         // Gotta resize now, and we don't know which direction, so try both?
911         let size = self.table.size();
912         self.make_some_room(size + 1);
913         if size > 0 {
914             self.make_some_room(size - 1);
915         }
916
917         let hash = self.make_hash(&key);
918         search_entry_hashed(&mut self.table, hash, key)
919     }
920
921     /// Return the number of elements in the map.
922     ///
923     /// # Example
924     ///
925     /// ```
926     /// use std::collections::HashMap;
927     ///
928     /// let mut a = HashMap::new();
929     /// assert_eq!(a.len(), 0);
930     /// a.insert(1u, "a");
931     /// assert_eq!(a.len(), 1);
932     /// ```
933     #[unstable = "matches collection reform specification, waiting for dust to settle"]
934     pub fn len(&self) -> uint { self.table.size() }
935
936     /// Return true if the map contains no elements.
937     ///
938     /// # Example
939     ///
940     /// ```
941     /// use std::collections::HashMap;
942     ///
943     /// let mut a = HashMap::new();
944     /// assert!(a.is_empty());
945     /// a.insert(1u, "a");
946     /// assert!(!a.is_empty());
947     /// ```
948     #[inline]
949     #[unstable = "matches collection reform specification, waiting for dust to settle"]
950     pub fn is_empty(&self) -> bool { self.len() == 0 }
951
952     /// Clears the map, removing all key-value pairs. Keeps the allocated memory
953     /// for reuse.
954     ///
955     /// # Example
956     ///
957     /// ```
958     /// use std::collections::HashMap;
959     ///
960     /// let mut a = HashMap::new();
961     /// a.insert(1u, "a");
962     /// a.clear();
963     /// assert!(a.is_empty());
964     /// ```
965     #[unstable = "matches collection reform specification, waiting for dust to settle"]
966     pub fn clear(&mut self) {
967         // Prevent reallocations from happening from now on. Makes it possible
968         // for the map to be reused but has a downside: reserves permanently.
969         self.resize_policy.reserve(self.table.size());
970
971         let cap = self.table.capacity();
972         let mut buckets = Bucket::first(&mut self.table);
973
974         while buckets.index() != cap {
975             buckets = match buckets.peek() {
976                 Empty(b)  => b.next(),
977                 Full(full) => {
978                     let (b, _, _) = full.take();
979                     b.next()
980                 }
981             };
982         }
983     }
984
985     /// Deprecated: Renamed to `get`.
986     #[deprecated = "Renamed to `get`"]
987     pub fn find(&self, k: &K) -> Option<&V> {
988         self.get(k)
989     }
990
991     /// Returns a reference to the value corresponding to the key.
992     ///
993     /// The key may be any borrowed form of the map's key type, but
994     /// `Hash` and `Eq` on the borrowed form *must* match those for
995     /// the key type.
996     ///
997     /// # Example
998     ///
999     /// ```
1000     /// use std::collections::HashMap;
1001     ///
1002     /// let mut map = HashMap::new();
1003     /// map.insert(1u, "a");
1004     /// assert_eq!(map.get(&1), Some(&"a"));
1005     /// assert_eq!(map.get(&2), None);
1006     /// ```
1007     #[unstable = "matches collection reform specification, waiting for dust to settle"]
1008     pub fn get<Sized? Q>(&self, k: &Q) -> Option<&V>
1009         where Q: Hash<S> + Eq + BorrowFrom<K>
1010     {
1011         self.search(k).map(|bucket| {
1012             let (_, v) = bucket.into_refs();
1013             v
1014         })
1015     }
1016
1017     /// Returns true if the map contains a value for the specified key.
1018     ///
1019     /// The key may be any borrowed form of the map's key type, but
1020     /// `Hash` and `Eq` on the borrowed form *must* match those for
1021     /// the key type.
1022     ///
1023     /// # Example
1024     ///
1025     /// ```
1026     /// use std::collections::HashMap;
1027     ///
1028     /// let mut map = HashMap::new();
1029     /// map.insert(1u, "a");
1030     /// assert_eq!(map.contains_key(&1), true);
1031     /// assert_eq!(map.contains_key(&2), false);
1032     /// ```
1033     #[unstable = "matches collection reform specification, waiting for dust to settle"]
1034     pub fn contains_key<Sized? Q>(&self, k: &Q) -> bool
1035         where Q: Hash<S> + Eq + BorrowFrom<K>
1036     {
1037         self.search(k).is_some()
1038     }
1039
1040     /// Deprecated: Renamed to `get_mut`.
1041     #[deprecated = "Renamed to `get_mut`"]
1042     pub fn find_mut(&mut self, k: &K) -> Option<&mut V> {
1043         self.get_mut(k)
1044     }
1045
1046     /// Returns a mutable reference to the value corresponding to the key.
1047     ///
1048     /// The key may be any borrowed form of the map's key type, but
1049     /// `Hash` and `Eq` on the borrowed form *must* match those for
1050     /// the key type.
1051     ///
1052     /// # Example
1053     ///
1054     /// ```
1055     /// use std::collections::HashMap;
1056     ///
1057     /// let mut map = HashMap::new();
1058     /// map.insert(1u, "a");
1059     /// match map.get_mut(&1) {
1060     ///     Some(x) => *x = "b",
1061     ///     None => (),
1062     /// }
1063     /// assert_eq!(map[1], "b");
1064     /// ```
1065     #[unstable = "matches collection reform specification, waiting for dust to settle"]
1066     pub fn get_mut<Sized? Q>(&mut self, k: &Q) -> Option<&mut V>
1067         where Q: Hash<S> + Eq + BorrowFrom<K>
1068     {
1069         match self.search_mut(k) {
1070             Some(bucket) => {
1071                 let (_, v) = bucket.into_mut_refs();
1072                 Some(v)
1073             }
1074             _ => None
1075         }
1076     }
1077
1078     /// Deprecated: Renamed to `insert`.
1079     #[deprecated = "Renamed to `insert`"]
1080     pub fn swap(&mut self, k: K, v: V) -> Option<V> {
1081         self.insert(k, v)
1082     }
1083
1084     /// Inserts a key-value pair from the map. If the key already had a value
1085     /// present in the map, that value is returned. Otherwise, `None` is returned.
1086     ///
1087     /// # Example
1088     ///
1089     /// ```
1090     /// use std::collections::HashMap;
1091     ///
1092     /// let mut map = HashMap::new();
1093     /// assert_eq!(map.insert(37u, "a"), None);
1094     /// assert_eq!(map.is_empty(), false);
1095     ///
1096     /// map.insert(37, "b");
1097     /// assert_eq!(map.insert(37, "c"), Some("b"));
1098     /// assert_eq!(map[37], "c");
1099     /// ```
1100     #[unstable = "matches collection reform specification, waiting for dust to settle"]
1101     pub fn insert(&mut self, k: K, v: V) -> Option<V> {
1102         let hash = self.make_hash(&k);
1103         let potential_new_size = self.table.size() + 1;
1104         self.make_some_room(potential_new_size);
1105
1106         let mut retval = None;
1107         self.insert_or_replace_with(hash, k, v, |_, val_ref, val| {
1108             retval = Some(replace(val_ref, val));
1109         });
1110         retval
1111     }
1112
1113     /// Deprecated: Renamed to `remove`.
1114     #[deprecated = "Renamed to `remove`"]
1115     pub fn pop(&mut self, k: &K) -> Option<V> {
1116         self.remove(k)
1117     }
1118
1119     /// Removes a key from the map, returning the value at the key if the key
1120     /// was previously in the map.
1121     ///
1122     /// The key may be any borrowed form of the map's key type, but
1123     /// `Hash` and `Eq` on the borrowed form *must* match those for
1124     /// the key type.
1125     ///
1126     /// # Example
1127     ///
1128     /// ```
1129     /// use std::collections::HashMap;
1130     ///
1131     /// let mut map = HashMap::new();
1132     /// map.insert(1u, "a");
1133     /// assert_eq!(map.remove(&1), Some("a"));
1134     /// assert_eq!(map.remove(&1), None);
1135     /// ```
1136     #[unstable = "matches collection reform specification, waiting for dust to settle"]
1137     pub fn remove<Sized? Q>(&mut self, k: &Q) -> Option<V>
1138         where Q: Hash<S> + Eq + BorrowFrom<K>
1139     {
1140         if self.table.size() == 0 {
1141             return None
1142         }
1143
1144         let potential_new_size = self.table.size() - 1;
1145         self.make_some_room(potential_new_size);
1146
1147         self.search_mut(k).map(|bucket| {
1148             let (_k, val) = pop_internal(bucket);
1149             val
1150         })
1151     }
1152 }
1153
1154 fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: K)
1155         -> Entry<'a, K, V> {
1156     // Worst case, we'll find one empty bucket among `size + 1` buckets.
1157     let size = table.size();
1158     let mut probe = Bucket::new(table, &hash);
1159     let ib = probe.index();
1160
1161     loop {
1162         let bucket = match probe.peek() {
1163             Empty(bucket) => {
1164                 // Found a hole!
1165                 return Vacant(VacantEntry {
1166                     hash: hash,
1167                     key: k,
1168                     elem: NoElem(bucket),
1169                 });
1170             },
1171             Full(bucket) => bucket
1172         };
1173
1174         if bucket.hash() == hash {
1175             let is_eq = {
1176                 let (bucket_k, _) = bucket.read();
1177                 k == *bucket_k
1178             };
1179
1180             if is_eq {
1181                 return Occupied(OccupiedEntry{
1182                     elem: bucket,
1183                 });
1184             }
1185         }
1186
1187         let robin_ib = bucket.index() as int - bucket.distance() as int;
1188
1189         if (ib as int) < robin_ib {
1190             // Found a luckier bucket than me. Better steal his spot.
1191             return Vacant(VacantEntry {
1192                 hash: hash,
1193                 key: k,
1194                 elem: NeqElem(bucket, robin_ib as uint),
1195             });
1196         }
1197
1198         probe = bucket.next();
1199         assert!(probe.index() != ib + size + 1);
1200     }
1201 }
1202
1203 impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
1204     /// Deprecated: Use `map.get(k).cloned()`.
1205     ///
1206     /// Return a copy of the value corresponding to the key.
1207     #[deprecated = "Use `map.get(k).cloned()`"]
1208     pub fn find_copy(&self, k: &K) -> Option<V> {
1209         self.get(k).cloned()
1210     }
1211
1212     /// Deprecated: Use `map[k].clone()`.
1213     ///
1214     /// Return a copy of the value corresponding to the key.
1215     #[deprecated = "Use `map[k].clone()`"]
1216     pub fn get_copy(&self, k: &K) -> V {
1217         self[*k].clone()
1218     }
1219 }
1220
1221 impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
1222     fn eq(&self, other: &HashMap<K, V, H>) -> bool {
1223         if self.len() != other.len() { return false; }
1224
1225         self.iter().all(|(key, value)|
1226             other.get(key).map_or(false, |v| *value == *v)
1227         )
1228     }
1229 }
1230
1231 impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {}
1232
1233 impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
1234     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1235         try!(write!(f, "{{"));
1236
1237         for (i, (k, v)) in self.iter().enumerate() {
1238             if i != 0 { try!(write!(f, ", ")); }
1239             try!(write!(f, "{}: {}", *k, *v));
1240         }
1241
1242         write!(f, "}}")
1243     }
1244 }
1245
1246 impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
1247     fn default() -> HashMap<K, V, H> {
1248         HashMap::with_hasher(Default::default())
1249     }
1250 }
1251
1252 impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> Index<Q, V> for HashMap<K, V, H>
1253     where Q: BorrowFrom<K> + Hash<S> + Eq
1254 {
1255     #[inline]
1256     fn index<'a>(&'a self, index: &Q) -> &'a V {
1257         self.get(index).expect("no entry found for key")
1258     }
1259 }
1260
1261 impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> IndexMut<Q, V> for HashMap<K, V, H>
1262     where Q: BorrowFrom<K> + Hash<S> + Eq
1263 {
1264     #[inline]
1265     fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
1266         match self.get_mut(index) {
1267             Some(v) => v,
1268             None => panic!("no entry found for key")
1269         }
1270     }
1271 }
1272
1273 /// HashMap iterator
1274 pub struct Entries<'a, K: 'a, V: 'a> {
1275     inner: table::Entries<'a, K, V>
1276 }
1277
1278 /// HashMap mutable values iterator
1279 pub struct MutEntries<'a, K: 'a, V: 'a> {
1280     inner: table::MutEntries<'a, K, V>
1281 }
1282
1283 /// HashMap move iterator
1284 pub struct MoveEntries<K, V> {
1285     inner: iter::Map<'static, (SafeHash, K, V), (K, V), table::MoveEntries<K, V>>
1286 }
1287
1288 /// A view into a single occupied location in a HashMap
1289 pub struct OccupiedEntry<'a, K:'a, V:'a> {
1290     elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
1291 }
1292
1293 /// A view into a single empty location in a HashMap
1294 pub struct VacantEntry<'a, K:'a, V:'a> {
1295     hash: SafeHash,
1296     key: K,
1297     elem: VacantEntryState<K,V, &'a mut RawTable<K, V>>,
1298 }
1299
1300 /// A view into a single location in a map, which may be vacant or occupied
1301 pub enum Entry<'a, K:'a, V:'a> {
1302     /// An occupied Entry
1303     Occupied(OccupiedEntry<'a, K, V>),
1304     /// A vacant Entry
1305     Vacant(VacantEntry<'a, K, V>),
1306 }
1307
1308 /// Possible states of a VacantEntry
1309 enum VacantEntryState<K, V, M> {
1310     /// The index is occupied, but the key to insert has precedence,
1311     /// and will kick the current one out on insertion
1312     NeqElem(FullBucket<K, V, M>, uint),
1313     /// The index is genuinely vacant
1314     NoElem(EmptyBucket<K, V, M>),
1315 }
1316
1317 impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
1318     #[inline]
1319     fn next(&mut self) -> Option<(&'a K, &'a V)> {
1320         self.inner.next()
1321     }
1322     #[inline]
1323     fn size_hint(&self) -> (uint, Option<uint>) {
1324         self.inner.size_hint()
1325     }
1326 }
1327
1328 impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
1329     #[inline]
1330     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1331         self.inner.next()
1332     }
1333     #[inline]
1334     fn size_hint(&self) -> (uint, Option<uint>) {
1335         self.inner.size_hint()
1336     }
1337 }
1338
1339 impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
1340     #[inline]
1341     fn next(&mut self) -> Option<(K, V)> {
1342         self.inner.next()
1343     }
1344     #[inline]
1345     fn size_hint(&self) -> (uint, Option<uint>) {
1346         self.inner.size_hint()
1347     }
1348 }
1349
1350 impl<'a, K, V> OccupiedEntry<'a, K, V> {
1351     /// Gets a reference to the value in the entry
1352     pub fn get(&self) -> &V {
1353         let (_, v) = self.elem.read();
1354         v
1355     }
1356
1357     /// Gets a mutable reference to the value in the entry
1358     pub fn get_mut(&mut self) -> &mut V {
1359         let (_, v) = self.elem.read_mut();
1360         v
1361     }
1362
1363     /// Converts the OccupiedEntry into a mutable reference to the value in the entry
1364     /// with a lifetime bound to the map itself
1365     pub fn into_mut(self) -> &'a mut V {
1366         let (_, v) = self.elem.into_mut_refs();
1367         v
1368     }
1369
1370     /// Sets the value of the entry, and returns the entry's old value
1371     pub fn set(&mut self, mut value: V) -> V {
1372         let old_value = self.get_mut();
1373         mem::swap(&mut value, old_value);
1374         value
1375     }
1376
1377     /// Takes the value out of the entry, and returns it
1378     pub fn take(self) -> V {
1379         let (_, _, v) = self.elem.take();
1380         v
1381     }
1382 }
1383
1384 impl<'a, K, V> VacantEntry<'a, K, V> {
1385     /// Sets the value of the entry with the VacantEntry's key,
1386     /// and returns a mutable reference to it
1387     pub fn set(self, value: V) -> &'a mut V {
1388         match self.elem {
1389             NeqElem(bucket, ib) => {
1390                 robin_hood(bucket, ib, self.hash, self.key, value)
1391             }
1392             NoElem(bucket) => {
1393                 let full = bucket.put(self.hash, self.key, value);
1394                 let (_, v) = full.into_mut_refs();
1395                 v
1396             }
1397         }
1398     }
1399 }
1400
1401 /// HashMap keys iterator
1402 pub type Keys<'a, K, V> =
1403     iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
1404
1405 /// HashMap values iterator
1406 pub type Values<'a, K, V> =
1407     iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
1408
1409 impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
1410     fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
1411         let (lower, _) = iter.size_hint();
1412         let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
1413         map.extend(iter);
1414         map
1415     }
1416 }
1417
1418 impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extend<(K, V)> for HashMap<K, V, H> {
1419     fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
1420         for (k, v) in iter {
1421             self.insert(k, v);
1422         }
1423     }
1424 }
1425
1426 #[cfg(test)]
1427 mod test_map {
1428     use prelude::*;
1429
1430     use super::HashMap;
1431     use super::{Occupied, Vacant};
1432     use cmp::Equiv;
1433     use hash;
1434     use iter::{Iterator,range_inclusive,range_step_inclusive};
1435     use cell::RefCell;
1436
1437     struct KindaIntLike(int);
1438
1439     impl Equiv<int> for KindaIntLike {
1440         fn equiv(&self, other: &int) -> bool {
1441             let KindaIntLike(this) = *self;
1442             this == *other
1443         }
1444     }
1445     impl<S: hash::Writer> hash::Hash<S> for KindaIntLike {
1446         fn hash(&self, state: &mut S) {
1447             let KindaIntLike(this) = *self;
1448             this.hash(state)
1449         }
1450     }
1451
1452     #[test]
1453     fn test_create_capacity_zero() {
1454         let mut m = HashMap::with_capacity(0);
1455
1456         assert!(m.insert(1i, 1i).is_none());
1457
1458         assert!(m.contains_key(&1));
1459         assert!(!m.contains_key(&0));
1460     }
1461
1462     #[test]
1463     fn test_insert() {
1464         let mut m = HashMap::new();
1465         assert_eq!(m.len(), 0);
1466         assert!(m.insert(1i, 2i).is_none());
1467         assert_eq!(m.len(), 1);
1468         assert!(m.insert(2i, 4i).is_none());
1469         assert_eq!(m.len(), 2);
1470         assert_eq!(*m.get(&1).unwrap(), 2);
1471         assert_eq!(*m.get(&2).unwrap(), 4);
1472     }
1473
1474     thread_local!(static DROP_VECTOR: RefCell<Vec<int>> = RefCell::new(Vec::new()))
1475
1476     #[deriving(Hash, PartialEq, Eq)]
1477     struct Dropable {
1478         k: uint
1479     }
1480
1481     impl Dropable {
1482         fn new(k: uint) -> Dropable {
1483             DROP_VECTOR.with(|slot| {
1484                 slot.borrow_mut()[k] += 1;
1485             });
1486
1487             Dropable { k: k }
1488         }
1489     }
1490
1491     impl Drop for Dropable {
1492         fn drop(&mut self) {
1493             DROP_VECTOR.with(|slot| {
1494                 slot.borrow_mut()[self.k] -= 1;
1495             });
1496         }
1497     }
1498
1499     impl Clone for Dropable {
1500         fn clone(&self) -> Dropable {
1501             Dropable::new(self.k)
1502         }
1503     }
1504
1505     #[test]
1506     fn test_drops() {
1507         DROP_VECTOR.with(|slot| {
1508             *slot.borrow_mut() = Vec::from_elem(200, 0i);
1509         });
1510
1511         {
1512             let mut m = HashMap::new();
1513
1514             DROP_VECTOR.with(|v| {
1515                 for i in range(0u, 200) {
1516                     assert_eq!(v.borrow().as_slice()[i], 0);
1517                 }
1518             });
1519
1520             for i in range(0u, 100) {
1521                 let d1 = Dropable::new(i);
1522                 let d2 = Dropable::new(i+100);
1523                 m.insert(d1, d2);
1524             }
1525
1526             DROP_VECTOR.with(|v| {
1527                 for i in range(0u, 200) {
1528                     assert_eq!(v.borrow().as_slice()[i], 1);
1529                 }
1530             });
1531
1532             for i in range(0u, 50) {
1533                 let k = Dropable::new(i);
1534                 let v = m.remove(&k);
1535
1536                 assert!(v.is_some());
1537
1538                 DROP_VECTOR.with(|v| {
1539                     assert_eq!(v.borrow().as_slice()[i], 1);
1540                     assert_eq!(v.borrow().as_slice()[i+100], 1);
1541                 });
1542             }
1543
1544             DROP_VECTOR.with(|v| {
1545                 for i in range(0u, 50) {
1546                     assert_eq!(v.borrow().as_slice()[i], 0);
1547                     assert_eq!(v.borrow().as_slice()[i+100], 0);
1548                 }
1549
1550                 for i in range(50u, 100) {
1551                     assert_eq!(v.borrow().as_slice()[i], 1);
1552                     assert_eq!(v.borrow().as_slice()[i+100], 1);
1553                 }
1554             });
1555         }
1556
1557         DROP_VECTOR.with(|v| {
1558             for i in range(0u, 200) {
1559                 assert_eq!(v.borrow().as_slice()[i], 0);
1560             }
1561         });
1562     }
1563
1564     #[test]
1565     fn test_move_iter_drops() {
1566         DROP_VECTOR.with(|v| {
1567             *v.borrow_mut() = Vec::from_elem(200, 0i);
1568         });
1569
1570         let hm = {
1571             let mut hm = HashMap::new();
1572
1573             DROP_VECTOR.with(|v| {
1574                 for i in range(0u, 200) {
1575                     assert_eq!(v.borrow().as_slice()[i], 0);
1576                 }
1577             });
1578
1579             for i in range(0u, 100) {
1580                 let d1 = Dropable::new(i);
1581                 let d2 = Dropable::new(i+100);
1582                 hm.insert(d1, d2);
1583             }
1584
1585             DROP_VECTOR.with(|v| {
1586                 for i in range(0u, 200) {
1587                     assert_eq!(v.borrow().as_slice()[i], 1);
1588                 }
1589             });
1590
1591             hm
1592         };
1593
1594         // By the way, ensure that cloning doesn't screw up the dropping.
1595         drop(hm.clone());
1596
1597         {
1598             let mut half = hm.into_iter().take(50);
1599
1600             DROP_VECTOR.with(|v| {
1601                 for i in range(0u, 200) {
1602                     assert_eq!(v.borrow().as_slice()[i], 1);
1603                 }
1604             });
1605
1606             for _ in half {}
1607
1608             DROP_VECTOR.with(|v| {
1609                 let nk = range(0u, 100).filter(|&i| {
1610                     v.borrow().as_slice()[i] == 1
1611                 }).count();
1612
1613                 let nv = range(0u, 100).filter(|&i| {
1614                     v.borrow().as_slice()[i+100] == 1
1615                 }).count();
1616
1617                 assert_eq!(nk, 50);
1618                 assert_eq!(nv, 50);
1619             });
1620         };
1621
1622         DROP_VECTOR.with(|v| {
1623             for i in range(0u, 200) {
1624                 assert_eq!(v.borrow().as_slice()[i], 0);
1625             }
1626         });
1627     }
1628
1629     #[test]
1630     fn test_empty_pop() {
1631         let mut m: HashMap<int, bool> = HashMap::new();
1632         assert_eq!(m.remove(&0), None);
1633     }
1634
1635     #[test]
1636     fn test_lots_of_insertions() {
1637         let mut m = HashMap::new();
1638
1639         // Try this a few times to make sure we never screw up the hashmap's
1640         // internal state.
1641         for _ in range(0i, 10) {
1642             assert!(m.is_empty());
1643
1644             for i in range_inclusive(1i, 1000) {
1645                 assert!(m.insert(i, i).is_none());
1646
1647                 for j in range_inclusive(1, i) {
1648                     let r = m.get(&j);
1649                     assert_eq!(r, Some(&j));
1650                 }
1651
1652                 for j in range_inclusive(i+1, 1000) {
1653                     let r = m.get(&j);
1654                     assert_eq!(r, None);
1655                 }
1656             }
1657
1658             for i in range_inclusive(1001i, 2000) {
1659                 assert!(!m.contains_key(&i));
1660             }
1661
1662             // remove forwards
1663             for i in range_inclusive(1i, 1000) {
1664                 assert!(m.remove(&i).is_some());
1665
1666                 for j in range_inclusive(1, i) {
1667                     assert!(!m.contains_key(&j));
1668                 }
1669
1670                 for j in range_inclusive(i+1, 1000) {
1671                     assert!(m.contains_key(&j));
1672                 }
1673             }
1674
1675             for i in range_inclusive(1i, 1000) {
1676                 assert!(!m.contains_key(&i));
1677             }
1678
1679             for i in range_inclusive(1i, 1000) {
1680                 assert!(m.insert(i, i).is_none());
1681             }
1682
1683             // remove backwards
1684             for i in range_step_inclusive(1000i, 1, -1) {
1685                 assert!(m.remove(&i).is_some());
1686
1687                 for j in range_inclusive(i, 1000) {
1688                     assert!(!m.contains_key(&j));
1689                 }
1690
1691                 for j in range_inclusive(1, i-1) {
1692                     assert!(m.contains_key(&j));
1693                 }
1694             }
1695         }
1696     }
1697
1698     #[test]
1699     fn test_find_mut() {
1700         let mut m = HashMap::new();
1701         assert!(m.insert(1i, 12i).is_none());
1702         assert!(m.insert(2i, 8i).is_none());
1703         assert!(m.insert(5i, 14i).is_none());
1704         let new = 100;
1705         match m.get_mut(&5) {
1706             None => panic!(), Some(x) => *x = new
1707         }
1708         assert_eq!(m.get(&5), Some(&new));
1709     }
1710
1711     #[test]
1712     fn test_insert_overwrite() {
1713         let mut m = HashMap::new();
1714         assert!(m.insert(1i, 2i).is_none());
1715         assert_eq!(*m.get(&1).unwrap(), 2);
1716         assert!(!m.insert(1i, 3i).is_none());
1717         assert_eq!(*m.get(&1).unwrap(), 3);
1718     }
1719
1720     #[test]
1721     fn test_insert_conflicts() {
1722         let mut m = HashMap::with_capacity(4);
1723         assert!(m.insert(1i, 2i).is_none());
1724         assert!(m.insert(5i, 3i).is_none());
1725         assert!(m.insert(9i, 4i).is_none());
1726         assert_eq!(*m.get(&9).unwrap(), 4);
1727         assert_eq!(*m.get(&5).unwrap(), 3);
1728         assert_eq!(*m.get(&1).unwrap(), 2);
1729     }
1730
1731     #[test]
1732     fn test_conflict_remove() {
1733         let mut m = HashMap::with_capacity(4);
1734         assert!(m.insert(1i, 2i).is_none());
1735         assert_eq!(*m.get(&1).unwrap(), 2);
1736         assert!(m.insert(5, 3).is_none());
1737         assert_eq!(*m.get(&1).unwrap(), 2);
1738         assert_eq!(*m.get(&5).unwrap(), 3);
1739         assert!(m.insert(9, 4).is_none());
1740         assert_eq!(*m.get(&1).unwrap(), 2);
1741         assert_eq!(*m.get(&5).unwrap(), 3);
1742         assert_eq!(*m.get(&9).unwrap(), 4);
1743         assert!(m.remove(&1).is_some());
1744         assert_eq!(*m.get(&9).unwrap(), 4);
1745         assert_eq!(*m.get(&5).unwrap(), 3);
1746     }
1747
1748     #[test]
1749     fn test_is_empty() {
1750         let mut m = HashMap::with_capacity(4);
1751         assert!(m.insert(1i, 2i).is_none());
1752         assert!(!m.is_empty());
1753         assert!(m.remove(&1).is_some());
1754         assert!(m.is_empty());
1755     }
1756
1757     #[test]
1758     fn test_pop() {
1759         let mut m = HashMap::new();
1760         m.insert(1i, 2i);
1761         assert_eq!(m.remove(&1), Some(2));
1762         assert_eq!(m.remove(&1), None);
1763     }
1764
1765     #[test]
1766     #[allow(experimental)]
1767     fn test_pop_equiv() {
1768         let mut m = HashMap::new();
1769         m.insert(1i, 2i);
1770         assert_eq!(m.pop_equiv(&KindaIntLike(1)), Some(2));
1771         assert_eq!(m.pop_equiv(&KindaIntLike(1)), None);
1772     }
1773
1774     #[test]
1775     fn test_iterate() {
1776         let mut m = HashMap::with_capacity(4);
1777         for i in range(0u, 32) {
1778             assert!(m.insert(i, i*2).is_none());
1779         }
1780         assert_eq!(m.len(), 32);
1781
1782         let mut observed: u32 = 0;
1783
1784         for (k, v) in m.iter() {
1785             assert_eq!(*v, *k * 2);
1786             observed |= 1 << *k;
1787         }
1788         assert_eq!(observed, 0xFFFF_FFFF);
1789     }
1790
1791     #[test]
1792     fn test_keys() {
1793         let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
1794         let map = vec.into_iter().collect::<HashMap<int, char>>();
1795         let keys = map.keys().map(|&k| k).collect::<Vec<int>>();
1796         assert_eq!(keys.len(), 3);
1797         assert!(keys.contains(&1));
1798         assert!(keys.contains(&2));
1799         assert!(keys.contains(&3));
1800     }
1801
1802     #[test]
1803     fn test_values() {
1804         let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
1805         let map = vec.into_iter().collect::<HashMap<int, char>>();
1806         let values = map.values().map(|&v| v).collect::<Vec<char>>();
1807         assert_eq!(values.len(), 3);
1808         assert!(values.contains(&'a'));
1809         assert!(values.contains(&'b'));
1810         assert!(values.contains(&'c'));
1811     }
1812
1813     #[test]
1814     fn test_find() {
1815         let mut m = HashMap::new();
1816         assert!(m.get(&1i).is_none());
1817         m.insert(1i, 2i);
1818         match m.get(&1) {
1819             None => panic!(),
1820             Some(v) => assert_eq!(*v, 2)
1821         }
1822     }
1823
1824     #[test]
1825     #[allow(deprecated)]
1826     fn test_find_copy() {
1827         let mut m = HashMap::new();
1828         assert!(m.get(&1i).is_none());
1829
1830         for i in range(1i, 10000) {
1831             m.insert(i, i + 7);
1832             match m.find_copy(&i) {
1833                 None => panic!(),
1834                 Some(v) => assert_eq!(v, i + 7)
1835             }
1836             for j in range(1i, i/100) {
1837                 match m.find_copy(&j) {
1838                     None => panic!(),
1839                     Some(v) => assert_eq!(v, j + 7)
1840                 }
1841             }
1842         }
1843     }
1844
1845     #[test]
1846     fn test_eq() {
1847         let mut m1 = HashMap::new();
1848         m1.insert(1i, 2i);
1849         m1.insert(2i, 3i);
1850         m1.insert(3i, 4i);
1851
1852         let mut m2 = HashMap::new();
1853         m2.insert(1i, 2i);
1854         m2.insert(2i, 3i);
1855
1856         assert!(m1 != m2);
1857
1858         m2.insert(3i, 4i);
1859
1860         assert_eq!(m1, m2);
1861     }
1862
1863     #[test]
1864     fn test_show() {
1865         let mut map: HashMap<int, int> = HashMap::new();
1866         let empty: HashMap<int, int> = HashMap::new();
1867
1868         map.insert(1i, 2i);
1869         map.insert(3i, 4i);
1870
1871         let map_str = format!("{}", map);
1872
1873         assert!(map_str == "{1: 2, 3: 4}".to_string() || map_str == "{3: 4, 1: 2}".to_string());
1874         assert_eq!(format!("{}", empty), "{}".to_string());
1875     }
1876
1877     #[test]
1878     fn test_expand() {
1879         let mut m = HashMap::new();
1880
1881         assert_eq!(m.len(), 0);
1882         assert!(m.is_empty());
1883
1884         let mut i = 0u;
1885         let old_cap = m.table.capacity();
1886         while old_cap == m.table.capacity() {
1887             m.insert(i, i);
1888             i += 1;
1889         }
1890
1891         assert_eq!(m.len(), i);
1892         assert!(!m.is_empty());
1893     }
1894
1895     #[test]
1896     fn test_resize_policy() {
1897         let mut m = HashMap::new();
1898
1899         assert_eq!(m.len(), 0);
1900         assert_eq!(m.table.capacity(), 0);
1901         assert!(m.is_empty());
1902
1903         m.insert(0, 0);
1904         m.remove(&0);
1905         assert!(m.is_empty());
1906         let initial_cap = m.table.capacity();
1907         m.reserve(initial_cap * 2);
1908         let cap = m.table.capacity();
1909
1910         assert_eq!(cap, initial_cap * 2);
1911
1912         let mut i = 0u;
1913         for _ in range(0, cap * 3 / 4) {
1914             m.insert(i, i);
1915             i += 1;
1916         }
1917         // three quarters full
1918
1919         assert_eq!(m.len(), i);
1920         assert_eq!(m.table.capacity(), cap);
1921
1922         for _ in range(0, cap / 4) {
1923             m.insert(i, i);
1924             i += 1;
1925         }
1926         // half full
1927
1928         let new_cap = m.table.capacity();
1929         assert_eq!(new_cap, cap * 2);
1930
1931         for _ in range(0, cap / 2 - 1) {
1932             i -= 1;
1933             m.remove(&i);
1934             assert_eq!(m.table.capacity(), new_cap);
1935         }
1936         // A little more than one quarter full.
1937         // Shrinking starts as we remove more elements:
1938         for _ in range(0, cap / 2 - 1) {
1939             i -= 1;
1940             m.remove(&i);
1941         }
1942
1943         assert_eq!(m.len(), i);
1944         assert!(!m.is_empty());
1945         assert_eq!(m.table.capacity(), cap);
1946     }
1947
1948     #[test]
1949     fn test_find_equiv() {
1950         let mut m = HashMap::new();
1951
1952         let (foo, bar, baz) = (1i,2i,3i);
1953         m.insert("foo".to_string(), foo);
1954         m.insert("bar".to_string(), bar);
1955         m.insert("baz".to_string(), baz);
1956
1957
1958         assert_eq!(m.get("foo"), Some(&foo));
1959         assert_eq!(m.get("bar"), Some(&bar));
1960         assert_eq!(m.get("baz"), Some(&baz));
1961
1962         assert_eq!(m.get("qux"), None);
1963     }
1964
1965     #[test]
1966     fn test_from_iter() {
1967         let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1968
1969         let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
1970
1971         for &(k, v) in xs.iter() {
1972             assert_eq!(map.get(&k), Some(&v));
1973         }
1974     }
1975
1976     #[test]
1977     fn test_size_hint() {
1978         let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1979
1980         let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
1981
1982         let mut iter = map.iter();
1983
1984         for _ in iter.by_ref().take(3) {}
1985
1986         assert_eq!(iter.size_hint(), (3, Some(3)));
1987     }
1988
1989     #[test]
1990     fn test_mut_size_hint() {
1991         let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
1992
1993         let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
1994
1995         let mut iter = map.iter_mut();
1996
1997         for _ in iter.by_ref().take(3) {}
1998
1999         assert_eq!(iter.size_hint(), (3, Some(3)));
2000     }
2001
2002     #[test]
2003     fn test_index() {
2004         let mut map: HashMap<int, int> = HashMap::new();
2005
2006         map.insert(1, 2);
2007         map.insert(2, 1);
2008         map.insert(3, 4);
2009
2010         assert_eq!(map[2], 1);
2011     }
2012
2013     #[test]
2014     #[should_fail]
2015     fn test_index_nonexistent() {
2016         let mut map: HashMap<int, int> = HashMap::new();
2017
2018         map.insert(1, 2);
2019         map.insert(2, 1);
2020         map.insert(3, 4);
2021
2022         map[4];
2023     }
2024
2025     #[test]
2026     fn test_entry(){
2027         let xs = [(1i, 10i), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
2028
2029         let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
2030
2031         // Existing key (insert)
2032         match map.entry(1) {
2033             Vacant(_) => unreachable!(),
2034             Occupied(mut view) => {
2035                 assert_eq!(view.get(), &10);
2036                 assert_eq!(view.set(100), 10);
2037             }
2038         }
2039         assert_eq!(map.get(&1).unwrap(), &100);
2040         assert_eq!(map.len(), 6);
2041
2042
2043         // Existing key (update)
2044         match map.entry(2) {
2045             Vacant(_) => unreachable!(),
2046             Occupied(mut view) => {
2047                 let v = view.get_mut();
2048                 let new_v = (*v) * 10;
2049                 *v = new_v;
2050             }
2051         }
2052         assert_eq!(map.get(&2).unwrap(), &200);
2053         assert_eq!(map.len(), 6);
2054
2055         // Existing key (take)
2056         match map.entry(3) {
2057             Vacant(_) => unreachable!(),
2058             Occupied(view) => {
2059                 assert_eq!(view.take(), 30);
2060             }
2061         }
2062         assert_eq!(map.get(&3), None);
2063         assert_eq!(map.len(), 5);
2064
2065
2066         // Inexistent key (insert)
2067         match map.entry(10) {
2068             Occupied(_) => unreachable!(),
2069             Vacant(view) => {
2070                 assert_eq!(*view.set(1000), 1000);
2071             }
2072         }
2073         assert_eq!(map.get(&10).unwrap(), &1000);
2074         assert_eq!(map.len(), 6);
2075     }
2076 }