blob: 91bee2adc20217fc536480a0b2afb941e651fc79 [file] [log] [blame]
Joel Galenson2370d122020-10-12 16:02:26 -07001//! A hash map where the keys are held by weak pointers and compared by key value.
2
3use std::borrow::Borrow;
4use std::cmp::max;
5use std::collections::hash_map::RandomState;
6use std::hash::{BuildHasher, Hash, Hasher};
7use std::fmt::{self, Debug, Formatter};
8use std::mem;
9
10use super::*;
11use super::size_policy::*;
12use super::traits::*;
13use super::util::*;
14
15pub use super::WeakKeyHashMap;
16
17/// Represents an entry in the table which may be occupied or vacant.
18pub enum Entry<'a, K: 'a + WeakKey, V: 'a> {
19 Occupied(OccupiedEntry<'a, K, V>),
20 Vacant(VacantEntry<'a, K, V>),
21}
22
23/// An occupied entry, which can be removed or viewed.
24pub struct OccupiedEntry<'a, K: 'a + WeakKey, V: 'a>(InnerEntry<'a, K, V>);
25
26/// A vacant entry, which can be inserted in or viewed.
27pub struct VacantEntry<'a, K: 'a + WeakKey, V: 'a>(InnerEntry<'a, K, V>);
28
29struct InnerEntry<'a, K: 'a + WeakKey, V: 'a> {
30 map: &'a mut WeakKeyInnerMap<K, V>,
31 pos: usize,
32 key: K::Strong,
33 hash_code: HashCode,
34}
35
36/// An iterator over the keys and values of the weak hash map.
37#[derive(Clone, Debug)]
38pub struct Iter<'a, K: 'a, V: 'a> {
39 base: ::std::slice::Iter<'a, Bucket<K, V>>,
40 size: usize,
41}
42
43impl<'a, K: WeakElement, V> Iterator for Iter<'a, K, V> {
44 type Item = (K::Strong, &'a V);
45
46 fn next(&mut self) -> Option<Self::Item> {
47 while let Some(bucket) = self.base.next() {
48 if let Some((ref weak_ptr, ref value, _)) = *bucket {
49 self.size -= 1;
50 if let Some(strong_ptr) = weak_ptr.view() {
51 return Some((strong_ptr, value));
52 }
53 }
54 }
55
56 None
57 }
58
59 fn size_hint(&self) -> (usize, Option<usize>) {
60 (0, Some(self.size))
61 }
62}
63
64#[derive(Debug)]
65/// An iterator over the keys and mutable values of the weak hash map.
66pub struct IterMut<'a, K: 'a, V: 'a> {
67 base: ::std::slice::IterMut<'a, Bucket<K, V>>,
68 size: usize,
69}
70
71impl<'a, K: WeakElement, V> Iterator for IterMut<'a, K, V> {
72 type Item = (K::Strong, &'a mut V);
73
74 fn next(&mut self) -> Option<Self::Item> {
75 while let Some(bucket) = self.base.next() {
76 if let Some((ref weak_ptr, ref mut value, _)) = *bucket {
77 self.size -= 1;
78 if let Some(strong_ptr) = weak_ptr.view() {
79 return Some((strong_ptr, value));
80 }
81 }
82 }
83
84 None
85 }
86
87 fn size_hint(&self) -> (usize, Option<usize>) {
88 (0, Some(self.size))
89 }
90}
91
92/// An iterator over the keys of the weak hash map.
93#[derive(Clone, Debug)]
94pub struct Keys<'a, K: 'a, V: 'a>(Iter<'a, K, V>);
95
96impl<'a, K: WeakElement, V> Iterator for Keys<'a, K, V> {
97 type Item = K::Strong;
98
99 fn next(&mut self) -> Option<Self::Item> {
100 self.0.next().map(|(k, _)| k)
101 }
102
103 fn size_hint(&self) -> (usize, Option<usize>) {
104 self.0.size_hint()
105 }
106}
107
108/// An iterator over the values of the weak hash map.
109#[derive(Clone, Debug)]
110pub struct Values<'a, K: 'a, V: 'a>(Iter<'a, K, V>);
111
112impl<'a, K: WeakElement, V> Iterator for Values<'a, K, V> {
113 type Item = &'a V;
114
115 fn next(&mut self) -> Option<Self::Item> {
116 self.0.next().map(|(_, v)| v)
117 }
118
119 fn size_hint(&self) -> (usize, Option<usize>) {
120 self.0.size_hint()
121 }
122}
123
124#[derive(Debug)]
125/// An iterator over the mutable values of the weak hash map.
126pub struct ValuesMut<'a, K: 'a, V: 'a>(IterMut<'a, K, V>);
127
128impl<'a, K: WeakElement, V> Iterator for ValuesMut<'a, K, V> {
129 type Item = &'a mut V;
130
131 fn next(&mut self) -> Option<Self::Item> {
132 self.0.next().map(|(_, v)| v)
133 }
134
135 fn size_hint(&self) -> (usize, Option<usize>) {
136 self.0.size_hint()
137 }
138}
139
140#[derive(Debug)]
141/// An iterator that consumes the values of a weak hash map, leaving it empty.
142pub struct Drain<'a, K: 'a, V: 'a> {
143 base: ::std::slice::IterMut<'a, Bucket<K, V>>,
144 size: usize,
145}
146
147impl<'a, K: WeakElement, V> Iterator for Drain<'a, K, V> {
148 type Item = (K::Strong, V);
149
150 fn next(&mut self) -> Option<Self::Item> {
151 while let Some(bucket) = self.base.next() {
152 if let Some((weak_ptr, value, _)) = bucket.take() {
153 self.size -= 1;
154 if let Some(strong_ptr) = weak_ptr.view() {
155 return Some((strong_ptr, value));
156 }
157 }
158 }
159
160 None
161 }
162
163 fn size_hint(&self) -> (usize, Option<usize>) {
164 (0, Some(self.size))
165 }
166}
167
168impl<'a, K, V> Drop for Drain<'a, K, V> {
169 fn drop(&mut self) {
170 while let Some(option) = self.base.next() {
171 *option = None;
172 }
173 }
174}
175
176/// An iterator that consumes the values of a weak hash map, leaving it empty.
177pub struct IntoIter<K, V> {
178 base: ::std::vec::IntoIter<Bucket<K, V>>,
179 size: usize,
180}
181
182impl<K: WeakElement, V> Iterator for IntoIter<K, V> {
183 type Item = (K::Strong, V);
184
185 fn next(&mut self) -> Option<Self::Item> {
186 while let Some(bucket) = self.base.next() {
187 if let Some((weak_ptr, value, _)) = bucket {
188 self.size -= 1;
189 if let Some(strong_ptr) = weak_ptr.view() {
190 return Some((strong_ptr, value));
191 }
192 }
193 }
194
195 None
196 }
197
198 fn size_hint(&self) -> (usize, Option<usize>) {
199 (0, Some(self.size))
200 }
201}
202
203impl<K: WeakKey, V> WeakKeyHashMap<K, V, RandomState>
204{
205 /// Creates an empty `WeakKeyHashMap`.
206 pub fn new() -> Self {
207 Self::with_capacity(DEFAULT_INITIAL_CAPACITY)
208 }
209
210 /// Creates an empty `WeakKeyHashMap` with the given capacity.
211 pub fn with_capacity(capacity: usize) -> Self {
212 Self::with_capacity_and_hasher(capacity, Default::default())
213 }
214}
215
216impl<K: WeakKey, V, S: BuildHasher> WeakKeyHashMap<K, V, S>
217{
218 /// Creates an empty `WeakKeyHashMap` with the given capacity and hasher.
219 pub fn with_hasher(hash_builder: S) -> Self {
220 Self::with_capacity_and_hasher(DEFAULT_INITIAL_CAPACITY, hash_builder)
221 }
222
223 /// Creates an empty `WeakKeyHashMap` with the given capacity and hasher.
224 pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
225 WeakKeyHashMap {
226 hash_builder,
227 inner: WeakKeyInnerMap {
228 buckets: new_boxed_option_slice(capacity),
229 len: 0,
230 }
231 }
232 }
233
234 /// Returns a reference to the map's `BuildHasher`.
235 pub fn hasher(&self) -> &S {
236 &self.hash_builder
237 }
238
239 /// Returns the number of elements the map can hold without reallocating.
240 pub fn capacity(&self) -> usize {
241 self.inner.capacity()
242 }
243
244 /// This has some preconditions.
245 fn resize(&mut self, capacity: usize) {
246 let old_buckets = mem::replace(&mut self.inner.buckets,
247 new_boxed_option_slice(capacity));
248
249 let iter = IntoIter {
250 base: old_buckets.into_vec().into_iter(),
251 size: self.inner.len,
252 };
253
254 self.inner.len = 0;
255
256 for (key, value) in iter {
257 self.entry_no_grow(key).or_insert(value);
258 }
259 }
260
261 /// Removes all mappings whose keys have expired.
262 pub fn remove_expired(&mut self) {
263 self.retain(|_, _| true)
264 }
265
266 /// Reserves room for additional elements.
267 pub fn reserve(&mut self, additional_capacity: usize) {
268 let new_capacity = additional_capacity + self.capacity();
269 self.resize(new_capacity);
270 }
271
272 /// Shrinks the capacity to the minimum allowed to hold the current number of elements.
273 pub fn shrink_to_fit(&mut self) {
274 self.remove_expired();
275 let new_capacity = (self.len() as f32 / COLLECT_LOAD_FACTOR).ceil() as usize;
276 self.resize(new_capacity);
277 }
278
279 /// Returns an over-approximation of the number of elements.
280 pub fn len(&self) -> usize {
281 self.inner.len
282 }
283
284 /// Is the map empty?
285 ///
286 /// Note that this may return false even if all keys in the map have
287 /// expired, if they haven't been collected yet.
288 pub fn is_empty(&self) -> bool {
289 self.len() == 0
290 }
291
292 /// The proportion of buckets that are used.
293 ///
294 /// This is an over-approximation because of expired keys.
295 pub fn load_factor(&self) -> f32 {
296 (self.len() as f32 + 1.0) / self.capacity() as f32
297 }
298
299 fn maybe_adjust_size(&mut self) {
300 if self.load_factor() > COLLECT_LOAD_FACTOR {
301 self.remove_expired();
302
303 let load_factor = self.load_factor();
304 let capacity = self.capacity();
305 if load_factor > GROW_LOAD_FACTOR {
306 self.resize(max(1, capacity * 2));
307 } else if load_factor < SHRINK_LOAD_FACTOR && capacity > DEFAULT_INITIAL_CAPACITY {
308 self.resize(max(1, capacity / 2));
309 }
310 }
311 }
312
313 /// Gets the requested entry.
314 pub fn entry(&mut self, key: K::Strong) -> Entry<K, V> {
315 self.maybe_adjust_size();
316 self.entry_no_grow(key)
317 }
318
319 fn entry_no_grow(&mut self, key: K::Strong) -> Entry<K, V> {
320 let mut inner = {
321 let hash_code = K::with_key(&key, |k| self.hash(k));
322 InnerEntry {
323 pos: self.which_bucket(hash_code),
324 map: &mut self.inner,
325 hash_code,
326 key,
327 }
328 };
329
330 for dist in 0 .. inner.capacity() {
331 match inner.bucket_status() {
332 BucketStatus::Unoccupied =>
333 return Entry::Vacant(VacantEntry(inner)),
334 BucketStatus::MatchesKey =>
335 return Entry::Occupied(OccupiedEntry(inner)),
336 BucketStatus::ProbeDistance(bucket_distance) => {
337 if bucket_distance < dist {
338 return Entry::Vacant(VacantEntry(inner))
339 } else {
340 inner.pos = inner.next_bucket(inner.pos);
341 }
342 }
343 }
344 }
345
346 panic!("WeakKeyHashTable::entry: out of space");
347 }
348
349 /// Removes all associations from the map.
350 pub fn clear(&mut self) {
351 self.drain();
352 }
353
354 fn find_bucket<Q>(&self, key: &Q) -> Option<(usize, K::Strong, HashCode)>
355 where Q: ?Sized + Hash + Eq,
356 K::Key: Borrow<Q>
357 {
358 if self.capacity() == 0 { return None; }
359
360 let hash_code = self.hash(key);
361 let mut pos = self.which_bucket(hash_code);
362
363 for dist in 0 .. self.capacity() {
364 if let Some((ref weak_key, _, bucket_hash_code)) = self.inner.buckets[pos] {
365 if bucket_hash_code == hash_code {
366 if let Some(bucket_key) = weak_key.view() {
367 if K::with_key(&bucket_key, |k| k.borrow() == key) {
368 return Some((pos, bucket_key, bucket_hash_code));
369 }
370 }
371 }
372
373 let bucket_dist =
374 self.probe_distance(pos, self.which_bucket(bucket_hash_code));
375 if bucket_dist < dist {
376 return None;
377 }
378 } else {
379 return None;
380 }
381
382 pos = self.next_bucket(pos);
383 }
384
385 None
386 }
387
388 /// Returns a reference to the value corresponding to the key.
389 pub fn get<Q>(&self, key: &Q) -> Option<&V>
390 where Q: ?Sized + Hash + Eq,
391 K::Key: Borrow<Q>
392 {
393 self.find_bucket(key).and_then(move |tup|
394 self.inner.buckets[tup.0].as_ref().map(|bucket| &bucket.1))
395 }
396
397 /// Returns true if the map contains the specified key.
398 pub fn contains_key<Q>(&self, key: &Q) -> bool
399 where Q: ?Sized + Hash + Eq,
400 K::Key: Borrow<Q>
401 {
402 self.find_bucket(key).is_some()
403 }
404
405 /// Returns a strong reference to the key, if found.
406 pub fn get_key<Q>(&self, key: &Q) -> Option<K::Strong>
407 where Q: ?Sized + Hash + Eq,
408 K::Key: Borrow<Q>
409 {
410 self.find_bucket(key).map(|tup| tup.1)
411 }
412
413 /// Returns a pair of a strong reference to the key, and a reference to the value, if present.
414 pub fn get_both<Q>(&self, key: &Q) -> Option<(K::Strong, &V)>
415 where Q: ?Sized + Hash + Eq,
416 K::Key: Borrow<Q>
417 {
418 self.find_bucket(key).and_then(move |tup|
419 self.inner.buckets[tup.0].as_ref().map(|bucket| (tup.1, &bucket.1)))
420 }
421
422 /// Returns a mutable reference to the value corresponding to the key.
423 pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
424 where Q: ?Sized + Hash + Eq,
425 K::Key: Borrow<Q>
426 {
427 self.find_bucket(key).and_then(move |tup|
428 self.inner.buckets[tup.0].as_mut().map(|bucket| &mut bucket.1))
429 }
430
431 /// Returns a pair of a strong reference to the key, and a mutable reference to the value,
432 /// if present.
433 pub fn get_both_mut<Q>(&mut self, key: &Q) -> Option<(K::Strong, &mut V)>
434 where Q: ?Sized + Hash + Eq,
435 K::Key: Borrow<Q>
436 {
437 self.find_bucket(key).and_then(move |tup|
438 self.inner.buckets[tup.0].as_mut().map(|bucket| (tup.1, &mut bucket.1)))
439 }
440
441 /// Unconditionally inserts the value, returning the old value if already present.
442 ///
443 /// Unlike `std::collections::HashMap`, this replaced the key even if occupied.
444 pub fn insert(&mut self, key: K::Strong, value: V) -> Option<V> {
445 match self.entry(key) {
446 Entry::Occupied(mut occupied) => {
447 Some(occupied.insert(value))
448 },
449 Entry::Vacant(vacant) => {
450 vacant.insert(value);
451 None
452 }
453 }
454 }
455
456 /// Removes the entry with the given key, if it exists, and returns the value.
457 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
458 where Q: ?Sized + Hash + Eq,
459 K::Key: Borrow<Q>
460 {
461 self.find_bucket(key).map(|(pos, strong_key, hash_code)| {
462 OccupiedEntry(InnerEntry {
463 map: &mut self.inner,
464 pos,
465 key: strong_key,
466 hash_code,
467 }).remove()
468 })
469 }
470
471 /// Removes all mappings not satisfying the given predicate.
472 ///
473 /// Also removes any expired mappings.
474 pub fn retain<F>(&mut self, mut f: F)
475 where F: FnMut(K::Strong, &mut V) -> bool
476 {
477 for i in 0 .. self.capacity() {
478 let remove = match self.inner.buckets[i] {
479 None => false,
480 Some(ref mut bucket) =>
481 match bucket.0.view() {
482 None => true,
483 Some(key) => !f(key, &mut bucket.1),
484 }
485 };
486
487 if remove {
488 self.inner.remove_index(i);
489 }
490 }
491 }
492
493 /// Is this map a submap of the other, using the given value comparison.
494 ///
495 /// In particular, all the keys of `self` must be in `other` and the values must compare
496 /// `true` with `value_equal`.
497 pub fn is_submap_with<F, S1, V1>(&self, other: &WeakKeyHashMap<K, V1, S1>,
498 mut value_equal: F) -> bool
499 where F: FnMut(&V, &V1) -> bool,
500 S1: BuildHasher
501 {
502 for (key, value1) in self {
503 if let Some(value2) = K::with_key(&key, |k| other.get(k)) {
504 if !value_equal(value1, value2) {
505 return false;
506 }
507 } else {
508 return false;
509 }
510 }
511
512 true
513 }
514
515 /// Is `self` a submap of `other`?
516 pub fn is_submap<V1, S1>(&self, other: &WeakKeyHashMap<K, V1, S1>) -> bool
517 where V: PartialEq<V1>,
518 S1: BuildHasher
519 {
520 self.is_submap_with(other, PartialEq::eq)
521 }
522
523 /// Are the keys of `self` a subset of the keys of `other`?
524 pub fn domain_is_subset<V1, S1>(&self, other: &WeakKeyHashMap<K, V1, S1>) -> bool
525 where S1: BuildHasher
526 {
527 self.is_submap_with(other, |_, _| true)
528 }
529
530 fn hash<Q>(&self, key: &Q) -> HashCode
531 where Q: ?Sized + Hash,
532 K::Key: Borrow<Q>
533 {
534 let mut hasher = self.hash_builder.build_hasher();
535 key.hash(&mut hasher);
536 HashCode(hasher.finish())
537 }
538}
539
540impl<K, V, V1, S, S1> PartialEq<WeakKeyHashMap<K, V1, S1>> for WeakKeyHashMap<K, V, S>
541 where K: WeakKey,
542 V: PartialEq<V1>,
543 S: BuildHasher,
544 S1: BuildHasher
545{
546 fn eq(&self, other: &WeakKeyHashMap<K, V1, S1>) -> bool {
547 self.is_submap(other) && other.domain_is_subset(self)
548 }
549}
550
551impl<K: WeakKey, V: Eq, S: BuildHasher> Eq for WeakKeyHashMap<K, V, S> { }
552
553impl<K: WeakKey, V, S: BuildHasher + Default> Default for WeakKeyHashMap<K, V, S> {
554 fn default() -> Self {
555 WeakKeyHashMap::with_hasher(Default::default())
556 }
557}
558
559impl<'a, K, V, S, Q> ::std::ops::Index<&'a Q> for WeakKeyHashMap<K, V, S>
560 where K: WeakKey,
561 K::Key: Borrow<Q>,
562 S: BuildHasher,
563 Q: ?Sized + Eq + Hash
564{
565 type Output = V;
566
567 fn index(&self, index: &'a Q) -> &Self::Output {
568 self.get(index).expect("Index::index: key not found")
569 }
570}
571
572impl<'a, K, V, S, Q> ::std::ops::IndexMut<&'a Q> for WeakKeyHashMap<K, V, S>
573 where K: WeakKey,
574 K::Key: Borrow<Q>,
575 S: BuildHasher,
576 Q: ?Sized + Eq + Hash
577{
578 fn index_mut(&mut self, index: &'a Q) -> &mut Self::Output {
579 self.get_mut(index).expect("IndexMut::index_mut: key not found")
580 }
581}
582
583impl<K, V, S> ::std::iter::FromIterator<(K::Strong, V)> for WeakKeyHashMap<K, V, S>
584 where K: WeakKey,
585 S: BuildHasher + Default
586{
587 fn from_iter<T: IntoIterator<Item=(K::Strong, V)>>(iter: T) -> Self {
588 let mut result = WeakKeyHashMap::with_hasher(Default::default());
589 result.extend(iter);
590 result
591 }
592}
593
594impl<K, V, S> ::std::iter::Extend<(K::Strong, V)> for WeakKeyHashMap<K, V, S>
595 where K: WeakKey,
596 S: BuildHasher
597{
598 fn extend<T: IntoIterator<Item=(K::Strong, V)>>(&mut self, iter: T) {
599 for (key, value) in iter {
600 self.insert(key, value);
601 }
602 }
603}
604
605impl<'a, K, V, S> ::std::iter::Extend<(&'a K::Strong, &'a V)> for WeakKeyHashMap<K, V, S>
606 where K: 'a + WeakKey,
607 K::Strong: Clone,
608 V: 'a + Clone,
609 S: BuildHasher
610{
611 fn extend<T: IntoIterator<Item=(&'a K::Strong, &'a V)>>(&mut self, iter: T) {
612 for (key, value) in iter {
613 self.insert(key.clone(), value.clone());
614 }
615 }
616}
617
618enum BucketStatus {
619 Unoccupied,
620 MatchesKey,
621 ProbeDistance(usize),
622}
623
624impl<'a, K: WeakKey, V> InnerEntry<'a, K, V> {
625 // Gets the status of the current bucket.
626 fn bucket_status(&self) -> BucketStatus {
627 match &self.map.buckets[self.pos] {
628 Some(bucket) => {
629 if bucket.2 == self.hash_code {
630 if let Some(key) = bucket.0.view() {
631 if K::with_key(&self.key, |k1| K::with_key(&key, |k2| k1 == k2)) {
632 return BucketStatus::MatchesKey;
633 }
634 }
635 }
636
637 let dist = self.probe_distance(self.pos,
638 self.which_bucket(bucket.2));
639 BucketStatus::ProbeDistance(dist)
640 },
641 None => BucketStatus::Unoccupied,
642 }
643 }
644}
645
646impl<'a, K: WeakKey, V> Entry<'a, K, V> {
647 /// Ensures a value is in the entry by inserting a default value
648 /// if empty, and returns a mutable reference to the value in the
649 /// entry.
650 pub fn or_insert(self, default: V) -> &'a mut V {
651 self.or_insert_with(|| default)
652 }
653
654 /// Ensures a value is in the entry by inserting the result of the
655 /// default function if empty, and returns a mutable reference to
656 /// the value in the entry.
657 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
658 match self {
659 Entry::Occupied(occupied) => occupied.into_mut(),
660 Entry::Vacant(vacant) => vacant.insert(default()),
661 }
662 }
663
664 /// Returns a reference to this entry's key.
665 pub fn key(&self) -> &K::Strong {
666 match *self {
667 Entry::Occupied(ref occupied) => occupied.key(),
668 Entry::Vacant(ref vacant) => vacant.key(),
669 }
670 }
671}
672
673impl<'a, K: WeakKey, V> OccupiedEntry<'a, K, V> {
674 /// Gets a reference to the key held by the entry.
675 pub fn key(&self) -> &K::Strong {
676 &self.0.key
677 }
678
679 /// Takes ownership of the key and value from the map.
680 pub fn remove_entry(self) -> (K::Strong, V) {
681 let (_, value, _) = self.0.map.buckets[self.0.pos].take().unwrap();
682 self.0.map.remove_index(self.0.pos);
683 (self.0.key, value)
684 }
685
686 /// Gets a reference to the value in the entry.
687 pub fn get(&self) -> &V {
688 &self.0.map.buckets[self.0.pos].as_ref().unwrap().1
689 }
690
691 /// Gets a mutable reference to the value in the entry.
692 pub fn get_mut(&mut self) -> &mut V {
693 &mut self.0.map.buckets[self.0.pos].as_mut().unwrap().1
694 }
695
696 /// Turns the entry into a mutable reference to the value borrowed from the map.
697 pub fn into_mut(self) -> &'a mut V {
698 &mut self.0.map.buckets[self.0.pos].as_mut().unwrap().1
699 }
700
701 /// Replaces the value in the entry with the given value.
702 pub fn insert(&mut self, mut value: V) -> V {
703 self.0.map.buckets[self.0.pos].as_mut().unwrap().0 = K::new(&self.0.key);
704 mem::swap(self.get_mut(), &mut value);
705 value
706 }
707
708 /// Removes the entry, returning the value.
709 pub fn remove(self) -> V {
710 self.remove_entry().1
711 }
712}
713
714impl<'a, K: WeakKey, V> VacantEntry<'a, K, V> {
715 /// Gets a reference to the key that would be used when inserting a
716 /// value through the `VacantEntry`.
717 pub fn key(&self) -> &K::Strong {
718 &self.0.key
719 }
720
721 /// Returns ownership of the key.
722 pub fn into_key(self) -> K::Strong {
723 self.0.key
724 }
725
726 /// Inserts the key and value into the map and return a mutable
727 /// reference to the value.
728 pub fn insert(self, value: V) -> &'a mut V {
729 let old_bucket = mem::replace(
730 &mut self.0.map.buckets[self.0.pos],
731 Some((K::new(&self.0.key), value, self.0.hash_code)));
732
733 if let Some(full_bucket) = old_bucket {
734 let next_bucket = self.next_bucket(self.0.pos);
735 self.0.map.steal(next_bucket, full_bucket);
736 }
737
738 self.0.map.len += 1;
739
740 &mut self.0.map.buckets[self.0.pos].as_mut().unwrap().1
741 }
742}
743
744impl<K: WeakKey, V> WeakKeyInnerMap<K, V> {
745 // Steals buckets starting at `pos`, replacing them with `bucket`.
746 fn steal(&mut self, mut pos: usize, mut bucket: FullBucket<K, V>) {
747 let mut my_dist = self.probe_distance(pos, self.which_bucket(bucket.2));
748
749 while let Some(hash_code) = self.buckets[pos].as_ref().and_then(
750 |bucket| if bucket.0.is_expired() {None} else {Some(bucket.2)}) {
751
752 let victim_dist = self.probe_distance(pos, self.which_bucket(hash_code));
753
754 if my_dist > victim_dist {
755 mem::swap(self.buckets[pos].as_mut().unwrap(), &mut bucket);
756 my_dist = victim_dist;
757 }
758
759 pos = self.next_bucket(pos);
760 my_dist += 1;
761 }
762
763 self.buckets[pos] = Some(bucket);
764 }
765
766 /// Removes the element at `dst`, shifting if necessary to preserve invariants.
767 fn remove_index(&mut self, mut dst: usize) {
768 let mut src = self.next_bucket(dst);
769
770 // We are going to remove the buckets in the range [dst, src)
771
772 loop {
773 let hash_code_option = self.buckets[src].as_ref().map(|tup| tup.2);
774
775 if let Some(hash_code) = hash_code_option {
776 let goal_pos = self.which_bucket(hash_code);
777 let dist = self.probe_distance(src, goal_pos);
778 if dist == 0 { break; }
779
780 if !self.buckets[src].as_ref().unwrap().0.is_expired() {
781 if in_interval(dst, goal_pos, src) {
782 self.erase_range(dst, goal_pos);
783 self.buckets[goal_pos] = self.buckets[src].take();
784 dst = self.next_bucket(goal_pos);
785 } else {
786 self.buckets[dst] = self.buckets[src].take();
787 dst = self.next_bucket(dst);
788 }
789 }
790 } else {
791 break;
792 }
793
794 src = self.next_bucket(src);
795 }
796
797 self.erase_range(dst, src);
798 }
799
800 /// Erases the (presumably expired, but not empty) elements in [start, limit).
801 fn erase_range(&mut self, mut start: usize, limit: usize)
802 {
803 while start != limit {
804 self.buckets[start] = None;
805 self.len -= 1;
806 start = self.next_bucket(start);
807 }
808 }
809}
810
811// Is value in [start, limit) modulo capacity?
812fn in_interval(start: usize, value: usize, limit: usize) -> bool
813{
814 if start <= limit {
815 start <= value && value < limit
816 } else {
817 start <= value || value < limit
818 }
819}
820
821// Helper trait for computing with indices modulo capacity.
822trait ModuloCapacity {
823 fn capacity(&self) -> usize;
824
825 fn probe_distance(&self, actual: usize, ideal: usize) -> usize {
826 if actual >= ideal {
827 actual - ideal
828 } else {
829 actual + self.capacity() - ideal
830 }
831 }
832
833 fn next_bucket(&self, pos: usize) -> usize {
834 assert_ne!( self.capacity(), 0 );
835 (pos + 1) % self.capacity()
836 }
837
838 fn which_bucket(&self, hash_code: HashCode) -> usize {
839 assert_ne!( self.capacity(), 0 );
840 (hash_code.0 as usize) % self.capacity()
841 }
842}
843
844impl<K, V> ModuloCapacity for WeakKeyInnerMap<K, V> {
845 fn capacity(&self) -> usize {
846 self.buckets.len()
847 }
848}
849
850impl<K, V, S> ModuloCapacity for WeakKeyHashMap<K, V, S> {
851 fn capacity(&self) -> usize {
852 self.inner.capacity()
853 }
854}
855
856impl<'a, K: WeakKey, V> ModuloCapacity for InnerEntry<'a, K, V> {
857 fn capacity(&self) -> usize {
858 self.map.capacity()
859 }
860}
861
862impl<'a, K: WeakKey, V> ModuloCapacity for OccupiedEntry<'a, K, V> {
863 fn capacity(&self) -> usize {
864 self.0.capacity()
865 }
866}
867
868impl<'a, K: WeakKey, V> ModuloCapacity for VacantEntry<'a, K, V> {
869 fn capacity(&self) -> usize {
870 self.0.capacity()
871 }
872}
873
874impl<K, V> Debug for WeakKeyInnerMap<K, V>
875 where K: WeakElement,
876 K::Strong: Debug,
877 V: Debug
878{
879 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
880 write!(f, "{{ ")?;
881 for (i, bucket) in self.buckets.iter().enumerate() {
882 if let Some((ref k, ref v, _)) = *bucket {
883 write!(f, "[{}] {:?} => {:?}, ", i, k.view(), *v)?;
884 }
885 }
886 write!(f, "}}")
887 }
888}
889
890impl<K: WeakElement, V: Debug, S> Debug for WeakKeyHashMap<K, V, S>
891 where K::Strong: Debug
892{
893 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
894 self.inner.fmt(f)
895 }
896}
897
898impl<'a, K: WeakKey, V: Debug> Debug for Entry<'a, K, V>
899 where K::Strong: Debug
900{
901 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
902 match *self {
903 Entry::Occupied(ref e) => e.fmt(f),
904 Entry::Vacant(ref e) => e.fmt(f),
905 }
906 }
907}
908
909impl<'a, K: WeakKey, V: Debug> Debug for OccupiedEntry<'a, K, V>
910 where K::Strong: Debug
911{
912 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
913 self.0.fmt(f)
914 }
915}
916
917impl<'a, K: WeakKey, V: Debug> Debug for VacantEntry<'a, K, V>
918 where K::Strong: Debug
919{
920 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
921 self.0.fmt(f)
922 }
923}
924
925impl<'a, K: WeakKey, V: Debug> Debug for InnerEntry<'a, K, V>
926 where K::Strong: Debug
927{
928 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
929 write!(f, "InnerEntry {{ pos = {}, buckets = {:?} }}", self.pos, self.map)
930 }
931}
932
933impl<K: WeakElement, V, S> IntoIterator for WeakKeyHashMap<K, V, S> {
934 type Item = (K::Strong, V);
935 type IntoIter = IntoIter<K, V>;
936
937 fn into_iter(self) -> Self::IntoIter {
938 IntoIter {
939 size: self.inner.len,
940 base: self.inner.buckets.into_vec().into_iter(),
941 }
942 }
943}
944
945impl<'a, K: WeakElement, V, S> IntoIterator for &'a WeakKeyHashMap<K, V, S> {
946 type Item = (K::Strong, &'a V);
947 type IntoIter = Iter<'a, K, V>;
948
949 fn into_iter(self) -> Self::IntoIter {
950 Iter {
951 base: self.inner.buckets.iter(),
952 size: self.inner.len,
953 }
954 }
955}
956
957impl<'a, K: WeakElement, V, S> IntoIterator for &'a mut WeakKeyHashMap<K, V, S> {
958 type Item = (K::Strong, &'a mut V);
959 type IntoIter = IterMut<'a, K, V>;
960
961 fn into_iter(self) -> Self::IntoIter {
962 IterMut {
963 base: self.inner.buckets.iter_mut(),
964 size: self.inner.len,
965 }
966 }
967}
968
969impl<K: WeakElement, V, S> WeakKeyHashMap<K, V, S> {
970 /// Gets an iterator over the keys and values.
971 pub fn iter(&self) -> Iter<K, V> {
972 self.into_iter()
973 }
974
975 /// Gets an iterator over the keys.
976 pub fn keys(&self) -> Keys<K, V> {
977 Keys(self.iter())
978 }
979
980 /// Gets an iterator over the values.
981 pub fn values(&self) -> Values<K, V> {
982 Values(self.iter())
983 }
984
985 /// Gets an iterator over the keys and mutable values.
986 pub fn iter_mut(&mut self) -> IterMut<K, V> {
987 self.into_iter()
988 }
989
990 /// Gets an iterator over the mutable values.
991 pub fn values_mut(&mut self) -> ValuesMut<K, V> {
992 ValuesMut(self.iter_mut())
993 }
994
995 /// Gets a draining iterator, which removes all the values but retains the storage.
996 pub fn drain(&mut self) -> Drain<K, V> {
997 let old_len = self.inner.len;
998 self.inner.len = 0;
999 Drain {
1000 base: self.inner.buckets.iter_mut(),
1001 size: old_len,
1002 }
1003 }
1004}
1005
1006#[cfg(test)]
1007mod tests {
1008 use std::rc::{Rc, Weak};
1009 use super::{Entry, WeakKeyHashMap};
1010
1011 #[test]
1012 fn simple() {
1013 let mut map: WeakKeyHashMap<Weak<str>, usize> = WeakKeyHashMap::new();
1014 assert_eq!( map.len(), 0 );
1015 assert!( !map.contains_key("five") );
1016
1017 let five: Rc<str> = Rc::from("five".to_string());
1018 map.insert(five.clone(), 5);
1019
1020 assert_eq!( map.len(), 1 );
1021 assert!( map.contains_key("five") );
1022
1023 drop(five);
1024
1025 assert_eq!( map.len(), 1 );
1026 assert!( !map.contains_key("five") );
1027
1028 map.remove_expired();
1029
1030 assert_eq!( map.len(), 0 );
1031 assert!( !map.contains_key("five") );
1032 }
1033
1034 // From https://github.com/tov/weak-table-rs/issues/1#issuecomment-461858060
1035 #[test]
1036 fn insert_and_check() {
1037 let mut rcs: Vec<Rc<u32>> = Vec::new();
1038
1039 for i in 0 .. 50 {
1040 rcs.push(Rc::new(i));
1041 }
1042
1043 let mut weakmap: WeakKeyHashMap<Weak<u32>, f32> = WeakKeyHashMap::new();
1044
1045 for key in rcs.iter().cloned() {
1046 let f = *key as f32 + 0.1;
1047 weakmap.insert(key, f);
1048 }
1049
1050 let mut count = 0;
1051
1052 for key in &rcs {
1053 assert_eq!(weakmap.get(key), Some(&(**key as f32 + 0.1)));
1054
1055 match weakmap.entry(Rc::clone(key)) {
1056 Entry::Occupied(_) => count += 1,
1057 Entry::Vacant(_) => eprintln!("WeakKeyHashMap: missing: {}", *key),
1058 }
1059 }
1060
1061 assert_eq!( count, rcs.len() );
1062 }
1063}