Coverage Report

Created: 2025-11-28 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/papaya-0.2.3/src/map.rs
Line
Count
Source
1
use crate::raw::utils::MapGuard;
2
use crate::raw::{self, InsertResult};
3
use crate::Equivalent;
4
use seize::{Collector, Guard, LocalGuard, OwnedGuard};
5
6
use std::collections::hash_map::RandomState;
7
use std::fmt;
8
use std::hash::{BuildHasher, Hash};
9
use std::marker::PhantomData;
10
11
/// A concurrent hash table.
12
///
13
/// Most hash table operations require a [`Guard`](crate::Guard), which can be acquired through
14
/// [`HashMap::guard`] or using the [`HashMap::pin`] API. See the [crate-level documentation](crate#usage)
15
/// for details.
16
pub struct HashMap<K, V, S = RandomState> {
17
    raw: raw::HashMap<K, V, S>,
18
}
19
20
// Safety: `HashMap` acts as a single-threaded collection on a single thread.
21
// References to keys and values cannot outlive the map's lifetime on a given
22
// thread.
23
unsafe impl<K: Send, V: Send, S: Send> Send for HashMap<K, V, S> {}
24
25
// Safety: We only ever hand out `&{K, V}` through shared references to the map,
26
// and never `&mut {K, V}` except through synchronized memory reclamation.
27
//
28
// However, we require `{K, V}: Send` as keys and values may be removed and dropped
29
// on a different thread than they were created on through shared access to the
30
// `HashMap`.
31
//
32
// Additionally, `HashMap` owns its `seize::Collector` and never exposes it,
33
// so multiple threads cannot be involved in reclamation without sharing the
34
// `HashMap` itself. If this was not true, we would require stricter bounds
35
// on `HashMap` operations themselves.
36
unsafe impl<K: Send + Sync, V: Send + Sync, S: Sync> Sync for HashMap<K, V, S> {}
37
38
/// A builder for a [`HashMap`].
39
///
40
/// # Examples
41
///
42
/// ```rust
43
/// use papaya::{HashMap, ResizeMode};
44
/// use seize::Collector;
45
/// use std::collections::hash_map::RandomState;
46
///
47
/// let map: HashMap<i32, i32> = HashMap::builder()
48
///     // Set the initial capacity.
49
///     .capacity(2048)
50
///     // Set the hasher.
51
///     .hasher(RandomState::new())
52
///     // Set the resize mode.
53
///     .resize_mode(ResizeMode::Blocking)
54
///     // Set a custom garbage collector.
55
///     .collector(Collector::new().batch_size(128))
56
///     // Construct the hash map.
57
///     .build();
58
/// ```
59
pub struct HashMapBuilder<K, V, S = RandomState> {
60
    hasher: S,
61
    capacity: usize,
62
    collector: Collector,
63
    resize_mode: ResizeMode,
64
    _kv: PhantomData<(K, V)>,
65
}
66
67
impl<K, V> HashMapBuilder<K, V> {
68
    /// Set the hash builder used to hash keys.
69
    ///
70
    /// Warning: `hash_builder` is normally randomly generated, and is designed
71
    /// to allow HashMaps to be resistant to attacks that cause many collisions
72
    /// and very poor performance. Setting it manually using this function can
73
    /// expose a DoS attack vector.
74
    ///
75
    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
76
    /// the HashMap to be useful, see its documentation for details.
77
0
    pub fn hasher<S>(self, hasher: S) -> HashMapBuilder<K, V, S> {
78
0
        HashMapBuilder {
79
0
            hasher,
80
0
            capacity: self.capacity,
81
0
            collector: self.collector,
82
0
            resize_mode: self.resize_mode,
83
0
            _kv: PhantomData,
84
0
        }
85
0
    }
86
}
87
88
impl<K, V, S> HashMapBuilder<K, V, S> {
89
    /// Set the initial capacity of the map.
90
    ///
91
    /// The table should be able to hold at least `capacity` elements before resizing.
92
    /// However, the capacity is an estimate, and the table may prematurely resize due
93
    /// to poor hash distribution. If `capacity` is 0, the hash map will not allocate.
94
0
    pub fn capacity(self, capacity: usize) -> HashMapBuilder<K, V, S> {
95
0
        HashMapBuilder {
96
0
            capacity,
97
0
            hasher: self.hasher,
98
0
            collector: self.collector,
99
0
            resize_mode: self.resize_mode,
100
0
            _kv: PhantomData,
101
0
        }
102
0
    }
103
104
    /// Set the resizing mode of the map. See [`ResizeMode`] for details.
105
0
    pub fn resize_mode(self, resize_mode: ResizeMode) -> Self {
106
0
        HashMapBuilder {
107
0
            resize_mode,
108
0
            hasher: self.hasher,
109
0
            capacity: self.capacity,
110
0
            collector: self.collector,
111
0
            _kv: PhantomData,
112
0
        }
113
0
    }
114
115
    /// Set the [`seize::Collector`] used for garbage collection.
116
    ///
117
    /// This method may be useful when you want more control over garbage collection.
118
    ///
119
    /// Note that all `Guard` references used to access the map must be produced by
120
    /// the provided `collector`.
121
0
    pub fn collector(self, collector: Collector) -> Self {
122
0
        HashMapBuilder {
123
0
            collector,
124
0
            hasher: self.hasher,
125
0
            capacity: self.capacity,
126
0
            resize_mode: self.resize_mode,
127
0
            _kv: PhantomData,
128
0
        }
129
0
    }
130
131
    /// Construct a [`HashMap`] from the builder, using the configured options.
132
0
    pub fn build(self) -> HashMap<K, V, S> {
133
0
        HashMap {
134
0
            raw: raw::HashMap::new(self.capacity, self.hasher, self.collector, self.resize_mode),
135
0
        }
136
0
    }
137
}
138
139
impl<K, V, S> fmt::Debug for HashMapBuilder<K, V, S> {
140
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141
0
        f.debug_struct("HashMapBuilder")
142
0
            .field("capacity", &self.capacity)
143
0
            .field("collector", &self.collector)
144
0
            .field("resize_mode", &self.resize_mode)
145
0
            .finish()
146
0
    }
147
}
148
149
/// Resize behavior for a [`HashMap`].
150
///
151
/// Hash maps must resize when the underlying table becomes full, migrating all key and value pairs
152
/// to a new table. This type allows you to configure the resizing behavior when passed to
153
/// [`HashMapBuilder::resize_mode`].
154
#[derive(Debug)]
155
pub enum ResizeMode {
156
    /// Writers copy a constant number of key/value pairs to the new table before making
157
    /// progress.
158
    ///
159
    /// Incremental resizes avoids latency spikes that can occur when insert operations have
160
    /// to resize a large table. However, they reduce parallelism during the resize and so can reduce
161
    /// overall throughput. Incremental resizing also means reads or write operations during an
162
    /// in-progress resize may have to search both the current and new table before succeeding, trading
163
    /// off median latency during a resize for tail latency.
164
    ///
165
    /// This is the default resize mode, with a chunk size of `64`.
166
    Incremental(usize),
167
    /// All writes to the map must wait till the resize completes before making progress.
168
    ///
169
    /// Blocking resizes tend to be better in terms of throughput, especially in setups with
170
    /// multiple writers that can perform the resize in parallel. However, they can lead to latency
171
    /// spikes for insert operations that have to resize large tables.
172
    ///
173
    /// If insert latency is not a concern, such as if the keys in your map are stable, enabling blocking
174
    /// resizes may yield better performance.
175
    ///
176
    /// Blocking resizing may also be a better option if you rely heavily on iteration or similar
177
    /// operations, as they require completing any in-progress resizes for consistency.
178
    Blocking,
179
}
180
181
impl Default for ResizeMode {
182
371
    fn default() -> Self {
183
        // Incremental resizing is a good default for most workloads as it avoids
184
        // unexpected latency spikes.
185
371
        ResizeMode::Incremental(64)
186
371
    }
187
}
188
189
impl<K, V> HashMap<K, V> {
190
    /// Creates an empty `HashMap`.
191
    ///
192
    /// The hash map is initially created with a capacity of 0, so it will not allocate
193
    /// until it is first inserted into.
194
    ///
195
    /// # Examples
196
    ///
197
    /// ```
198
    /// use papaya::HashMap;
199
    /// let map: HashMap<&str, i32> = HashMap::new();
200
    /// ```
201
0
    pub fn new() -> HashMap<K, V> {
202
0
        HashMap::with_capacity_and_hasher(0, RandomState::new())
203
0
    }
204
205
    /// Creates an empty `HashMap` with the specified capacity.
206
    ///
207
    /// The table should be able to hold at least `capacity` elements before resizing.
208
    /// However, the capacity is an estimate, and the table may prematurely resize due
209
    /// to poor hash distribution. If `capacity` is 0, the hash map will not allocate.
210
    ///
211
    /// Note that the `HashMap` may grow and shrink as elements are inserted or removed,
212
    /// but it is guaranteed to never shrink below the initial capacity.
213
    ///
214
    /// # Examples
215
    ///
216
    /// ```
217
    /// use papaya::HashMap;
218
    /// let map: HashMap<&str, i32> = HashMap::with_capacity(10);
219
    /// ```
220
0
    pub fn with_capacity(capacity: usize) -> HashMap<K, V> {
221
0
        HashMap::with_capacity_and_hasher(capacity, RandomState::new())
222
0
    }
223
224
    /// Returns a builder for a `HashMap`.
225
    ///
226
    /// The builder can be used for more complex configuration, such as using
227
    /// a custom [`Collector`], or [`ResizeMode`].
228
0
    pub fn builder() -> HashMapBuilder<K, V> {
229
0
        HashMapBuilder {
230
0
            capacity: 0,
231
0
            hasher: RandomState::default(),
232
0
            collector: Collector::new(),
233
0
            resize_mode: ResizeMode::default(),
234
0
            _kv: PhantomData,
235
0
        }
236
0
    }
237
}
238
239
impl<K, V, S> Default for HashMap<K, V, S>
240
where
241
    S: Default,
242
{
243
0
    fn default() -> Self {
244
0
        HashMap::with_hasher(S::default())
245
0
    }
246
}
247
248
impl<K, V, S> HashMap<K, V, S> {
249
    /// Creates an empty `HashMap` which will use the given hash builder to hash
250
    /// keys.
251
    ///
252
    /// Warning: `hash_builder` is normally randomly generated, and is designed
253
    /// to allow HashMaps to be resistant to attacks that cause many collisions
254
    /// and very poor performance. Setting it manually using this function can
255
    /// expose a DoS attack vector.
256
    ///
257
    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
258
    /// the HashMap to be useful, see its documentation for details.
259
    ///
260
    /// # Examples
261
    ///
262
    /// ```
263
    /// use papaya::HashMap;
264
    /// use std::hash::RandomState;
265
    ///
266
    /// let s = RandomState::new();
267
    /// let map = HashMap::with_hasher(s);
268
    /// map.pin().insert(1, 2);
269
    /// ```
270
0
    pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
271
0
        HashMap::with_capacity_and_hasher(0, hash_builder)
272
0
    }
273
274
    /// Creates an empty `HashMap` with at least the specified capacity, using
275
    /// `hash_builder` to hash the keys.
276
    ///
277
    /// The table should be able to hold at least `capacity` elements before resizing.
278
    /// However, the capacity is an estimate, and the table may prematurely resize due
279
    /// to poor hash distribution. If `capacity` is 0, the hash map will not allocate.
280
    ///
281
    /// Warning: `hash_builder` is normally randomly generated, and is designed
282
    /// to allow HashMaps to be resistant to attacks that cause many collisions
283
    /// and very poor performance. Setting it manually using this function can
284
    /// expose a DoS attack vector.
285
    ///
286
    /// The `hasher` passed should implement the [`BuildHasher`] trait for
287
    /// the HashMap to be useful, see its documentation for details.
288
    ///
289
    /// # Examples
290
    ///
291
    /// ```
292
    /// use papaya::HashMap;
293
    /// use std::hash::RandomState;
294
    ///
295
    /// let s = RandomState::new();
296
    /// let map = HashMap::with_capacity_and_hasher(10, s);
297
    /// map.pin().insert(1, 2);
298
    /// ```
299
0
    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
300
0
        HashMap {
301
0
            raw: raw::HashMap::new(
302
0
                capacity,
303
0
                hash_builder,
304
0
                Collector::default(),
305
0
                ResizeMode::default(),
306
0
            ),
307
0
        }
308
0
    }
309
310
    /// Returns a pinned reference to the map.
311
    ///
312
    /// The returned reference manages a guard internally, preventing garbage collection
313
    /// for as long as it is held. See the [crate-level documentation](crate#usage) for details.
314
    #[inline]
315
0
    pub fn pin(&self) -> HashMapRef<'_, K, V, S, LocalGuard<'_>> {
316
0
        HashMapRef {
317
0
            guard: self.raw.guard(),
318
0
            map: self,
319
0
        }
320
0
    }
321
322
    /// Returns a pinned reference to the map.
323
    ///
324
    /// Unlike [`HashMap::pin`], the returned reference implements `Send` and `Sync`,
325
    /// allowing it to be held across `.await` points in work-stealing schedulers.
326
    /// This is especially useful for iterators.
327
    ///
328
    /// The returned reference manages a guard internally, preventing garbage collection
329
    /// for as long as it is held. See the [crate-level documentation](crate#usage) for details.
330
    #[inline]
331
0
    pub fn pin_owned(&self) -> HashMapRef<'_, K, V, S, OwnedGuard<'_>> {
332
0
        HashMapRef {
333
0
            guard: self.raw.owned_guard(),
334
0
            map: self,
335
0
        }
336
0
    }
337
338
    /// Returns a guard for use with this map.
339
    ///
340
    /// Note that holding on to a guard prevents garbage collection.
341
    /// See the [crate-level documentation](crate#usage) for details.
342
    #[inline]
343
0
    pub fn guard(&self) -> LocalGuard<'_> {
344
0
        self.raw.collector().enter()
345
0
    }
346
347
    /// Returns an owned guard for use with this map.
348
    ///
349
    /// Owned guards implement `Send` and `Sync`, allowing them to be held across
350
    /// `.await` points in work-stealing schedulers. This is especially useful
351
    /// for iterators.
352
    ///
353
    /// Note that holding on to a guard prevents garbage collection.
354
    /// See the [crate-level documentation](crate#usage) for details.
355
    #[inline]
356
0
    pub fn owned_guard(&self) -> OwnedGuard<'_> {
357
0
        self.raw.collector().enter_owned()
358
0
    }
359
}
360
361
impl<K, V, S> HashMap<K, V, S>
362
where
363
    K: Hash + Eq,
364
    S: BuildHasher,
365
{
366
    /// Returns the number of entries in the map.
367
    ///
368
    /// # Examples
369
    ///
370
    /// ```
371
    /// use papaya::HashMap;
372
    ///
373
    /// let map = HashMap::new();
374
    ///
375
    /// map.pin().insert(1, "a");
376
    /// map.pin().insert(2, "b");
377
    /// assert!(map.len() == 2);
378
    /// ```
379
    #[inline]
380
0
    pub fn len(&self) -> usize {
381
0
        self.raw.len()
382
0
    }
383
384
    /// Returns `true` if the map is empty. Otherwise returns `false`.
385
    ///
386
    /// # Examples
387
    ///
388
    /// ```
389
    /// use papaya::HashMap;
390
    ///
391
    /// let map = HashMap::new();
392
    /// assert!(map.is_empty());
393
    /// map.pin().insert("a", 1);
394
    /// assert!(!map.is_empty());
395
    /// ```
396
    #[inline]
397
0
    pub fn is_empty(&self) -> bool {
398
0
        self.len() == 0
399
0
    }
400
401
    /// Returns `true` if the map contains a value for the specified key.
402
    ///
403
    /// The key may be any borrowed form of the map's key type, but
404
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
405
    /// the key type.
406
    ///
407
    /// [`Eq`]: std::cmp::Eq
408
    /// [`Hash`]: std::hash::Hash
409
    ///
410
    ///
411
    /// # Examples
412
    ///
413
    /// ```
414
    /// use papaya::HashMap;
415
    ///
416
    /// let map = HashMap::new();
417
    /// map.pin().insert(1, "a");
418
    /// assert_eq!(map.pin().contains_key(&1), true);
419
    /// assert_eq!(map.pin().contains_key(&2), false);
420
    /// ```
421
    #[inline]
422
0
    pub fn contains_key<Q>(&self, key: &Q, guard: &impl Guard) -> bool
423
0
    where
424
0
        Q: Equivalent<K> + Hash + ?Sized,
425
    {
426
0
        self.get(key, self.raw.verify(guard)).is_some()
427
0
    }
428
429
    /// Returns a reference to the value corresponding to the key.
430
    ///
431
    /// The key may be any borrowed form of the map's key type, but
432
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
433
    /// the key type.
434
    ///
435
    /// [`Eq`]: std::cmp::Eq
436
    /// [`Hash`]: std::hash::Hash
437
    ///
438
    /// # Examples
439
    ///
440
    /// ```
441
    /// use papaya::HashMap;
442
    ///
443
    /// let map = HashMap::new();
444
    /// map.pin().insert(1, "a");
445
    /// assert_eq!(map.pin().get(&1), Some(&"a"));
446
    /// assert_eq!(map.pin().get(&2), None);
447
    /// ```
448
    #[inline]
449
0
    pub fn get<'g, Q>(&self, key: &Q, guard: &'g impl Guard) -> Option<&'g V>
450
0
    where
451
0
        K: 'g,
452
0
        Q: Equivalent<K> + Hash + ?Sized,
453
    {
454
0
        match self.raw.get(key, self.raw.verify(guard)) {
455
0
            Some((_, v)) => Some(v),
456
0
            None => None,
457
        }
458
0
    }
459
460
    /// Returns the key-value pair corresponding to the supplied key.
461
    ///
462
    /// The supplied key may be any borrowed form of the map's key type, but
463
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
464
    /// the key type.
465
    ///
466
    /// [`Eq`]: std::cmp::Eq
467
    /// [`Hash`]: std::hash::Hash
468
    ///
469
    /// # Examples
470
    ///
471
    /// ```
472
    /// use papaya::HashMap;
473
    ///
474
    /// let map = HashMap::new();
475
    /// map.pin().insert(1, "a");
476
    /// assert_eq!(map.pin().get_key_value(&1), Some((&1, &"a")));
477
    /// assert_eq!(map.pin().get_key_value(&2), None);
478
    /// ```
479
    #[inline]
480
0
    pub fn get_key_value<'g, Q>(&self, key: &Q, guard: &'g impl Guard) -> Option<(&'g K, &'g V)>
481
0
    where
482
0
        Q: Equivalent<K> + Hash + ?Sized,
483
    {
484
0
        self.raw.get(key, self.raw.verify(guard))
485
0
    }
486
487
    /// Inserts a key-value pair into the map.
488
    ///
489
    /// If the map did not have this key present, [`None`] is returned.
490
    ///
491
    /// If the map did have this key present, the value is updated, and the old
492
    /// value is returned. The key is not updated, though; this matters for
493
    /// types that can be `==` without being identical. See the [standard library
494
    /// documentation] for details.
495
    ///
496
    /// [standard library documentation]: https://doc.rust-lang.org/std/collections/index.html#insert-and-complex-keys
497
    ///
498
    /// # Examples
499
    ///
500
    /// ```
501
    /// use papaya::HashMap;
502
    ///
503
    /// let map = HashMap::new();
504
    /// assert_eq!(map.pin().insert(37, "a"), None);
505
    /// assert_eq!(map.pin().is_empty(), false);
506
    ///
507
    /// map.pin().insert(37, "b");
508
    /// assert_eq!(map.pin().insert(37, "c"), Some(&"b"));
509
    /// assert_eq!(map.pin().get(&37), Some(&"c"));
510
    /// ```
511
    #[inline]
512
0
    pub fn insert<'g>(&self, key: K, value: V, guard: &'g impl Guard) -> Option<&'g V> {
513
0
        match self.raw.insert(key, value, true, self.raw.verify(guard)) {
514
0
            InsertResult::Inserted(_) => None,
515
0
            InsertResult::Replaced(value) => Some(value),
516
0
            InsertResult::Error { .. } => unreachable!(),
517
        }
518
0
    }
519
520
    /// Tries to insert a key-value pair into the map, and returns
521
    /// a reference to the value that was inserted.
522
    ///
523
    /// If the map already had this key present, nothing is updated, and
524
    /// an error containing the existing value is returned.
525
    ///
526
    /// # Examples
527
    ///
528
    /// ```
529
    /// use papaya::HashMap;
530
    ///
531
    /// let map = HashMap::new();
532
    /// let map = map.pin();
533
    ///
534
    /// assert_eq!(map.try_insert(37, "a").unwrap(), &"a");
535
    ///
536
    /// let err = map.try_insert(37, "b").unwrap_err();
537
    /// assert_eq!(err.current, &"a");
538
    /// assert_eq!(err.not_inserted, "b");
539
    /// ```
540
    #[inline]
541
0
    pub fn try_insert<'g>(
542
0
        &self,
543
0
        key: K,
544
0
        value: V,
545
0
        guard: &'g impl Guard,
546
0
    ) -> Result<&'g V, OccupiedError<'g, V>> {
547
        // Safety: Checked the guard above.
548
0
        match self.raw.insert(key, value, false, self.raw.verify(guard)) {
549
0
            InsertResult::Inserted(value) => Ok(value),
550
            InsertResult::Error {
551
0
                current,
552
0
                not_inserted,
553
0
            } => Err(OccupiedError {
554
0
                current,
555
0
                not_inserted,
556
0
            }),
557
0
            InsertResult::Replaced(_) => unreachable!(),
558
        }
559
0
    }
560
561
    /// Tries to insert a key and value computed from a closure into the map,
562
    /// and returns a reference to the value that was inserted.
563
    ///
564
    /// If the map already had this key present, nothing is updated, and
565
    /// the existing value is returned.
566
    ///
567
    /// # Examples
568
    ///
569
    /// ```
570
    /// use papaya::HashMap;
571
    ///
572
    /// let map = HashMap::new();
573
    /// let map = map.pin();
574
    ///
575
    /// assert_eq!(map.try_insert_with(37, || "a").unwrap(), &"a");
576
    ///
577
    /// let current = map.try_insert_with(37, || "b").unwrap_err();
578
    /// assert_eq!(current, &"a");
579
    /// ```
580
    #[inline]
581
0
    pub fn try_insert_with<'g, F>(
582
0
        &self,
583
0
        key: K,
584
0
        f: F,
585
0
        guard: &'g impl Guard,
586
0
    ) -> Result<&'g V, &'g V>
587
0
    where
588
0
        F: FnOnce() -> V,
589
0
        K: 'g,
590
    {
591
0
        self.raw.try_insert_with(key, f, self.raw.verify(guard))
592
0
    }
593
594
    /// Returns a reference to the value corresponding to the key, or inserts a default value.
595
    ///
596
    /// If the given key is present, the corresponding value is returned. If it is not present,
597
    /// the provided `value` is inserted, and a reference to the newly inserted value is returned.
598
    ///
599
    /// # Examples
600
    ///
601
    /// ```
602
    /// use papaya::HashMap;
603
    ///
604
    /// let map = HashMap::new();
605
    /// assert_eq!(map.pin().get_or_insert("a", 3), &3);
606
    /// assert_eq!(map.pin().get_or_insert("a", 6), &3);
607
    /// ```
608
    #[inline]
609
0
    pub fn get_or_insert<'g>(&self, key: K, value: V, guard: &'g impl Guard) -> &'g V {
610
        // Note that we use `try_insert` instead of `compute` or `get_or_insert_with` here, as it
611
        // allows us to avoid the closure indirection.
612
0
        match self.try_insert(key, value, guard) {
613
0
            Ok(inserted) => inserted,
614
0
            Err(OccupiedError { current, .. }) => current,
615
        }
616
0
    }
617
618
    /// Returns a reference to the value corresponding to the key, or inserts a default value
619
    /// computed from a closure.
620
    ///
621
    /// If the given key is present, the corresponding value is returned. If it is not present,
622
    /// the value computed from `f` is inserted, and a reference to the newly inserted value is
623
    /// returned.
624
    ///
625
    ///
626
    /// # Examples
627
    ///
628
    /// ```
629
    /// use papaya::HashMap;
630
    ///
631
    /// let map = HashMap::new();
632
    /// assert_eq!(map.pin().get_or_insert_with("a", || 3), &3);
633
    /// assert_eq!(map.pin().get_or_insert_with("a", || 6), &3);
634
    /// ```
635
    #[inline]
636
0
    pub fn get_or_insert_with<'g, F>(&self, key: K, f: F, guard: &'g impl Guard) -> &'g V
637
0
    where
638
0
        F: FnOnce() -> V,
639
0
        K: 'g,
640
    {
641
0
        self.raw.get_or_insert_with(key, f, self.raw.verify(guard))
642
0
    }
643
644
    /// Updates an existing entry atomically.
645
    ///
646
    /// If the value for the specified `key` is present, the new value is computed and stored the
647
    /// using the provided update function, and the new value is returned. Otherwise, `None`
648
    /// is returned.
649
    ///
650
    ///
651
    /// The update function is given the current value associated with the given key and returns the
652
    /// new value to be stored. The operation is applied atomically only if the state of the entry remains
653
    /// the same, meaning that it is not concurrently modified in any way. If the entry is
654
    /// modified, the operation is retried with the new entry, similar to a traditional [compare-and-swap](https://en.wikipedia.org/wiki/Compare-and-swap)
655
    /// operation.
656
    ///
657
    /// Note that the `update` function should be pure as it may be called multiple times, and the output
658
    /// for a given entry may be memoized across retries.
659
    ///
660
    ///
661
    /// # Examples
662
    ///
663
    /// ```
664
    /// use papaya::HashMap;
665
    ///
666
    /// let map = HashMap::new();
667
    /// map.pin().insert("a", 1);
668
    /// assert_eq!(map.pin().get(&"a"), Some(&1));
669
    ///
670
    /// map.pin().update("a", |v| v + 1);
671
    /// assert_eq!(map.pin().get(&"a"), Some(&2));
672
    /// ```
673
    #[inline]
674
0
    pub fn update<'g, F>(&self, key: K, update: F, guard: &'g impl Guard) -> Option<&'g V>
675
0
    where
676
0
        F: Fn(&V) -> V,
677
0
        K: 'g,
678
    {
679
0
        self.raw.update(key, update, self.raw.verify(guard))
680
0
    }
681
682
    /// Updates an existing entry or inserts a default value.
683
    ///
684
    /// If the value for the specified `key` is present, the new value is computed and stored the
685
    /// using the provided update function, and the new value is returned. Otherwise, the provided
686
    /// `value` is inserted into the map, and a reference to the newly inserted value is returned.
687
    ///
688
    /// See [`HashMap::update`] for details about how atomic updates are performed.
689
    ///
690
    /// # Examples
691
    ///
692
    /// ```
693
    /// use papaya::HashMap;
694
    ///
695
    /// let map = HashMap::new();
696
    /// assert_eq!(*map.pin().update_or_insert("a", |i| i + 1, 0), 0);
697
    /// assert_eq!(*map.pin().update_or_insert("a", |i| i + 1, 0), 1);
698
    /// ```
699
    #[inline]
700
0
    pub fn update_or_insert<'g, F>(
701
0
        &self,
702
0
        key: K,
703
0
        update: F,
704
0
        value: V,
705
0
        guard: &'g impl Guard,
706
0
    ) -> &'g V
707
0
    where
708
0
        F: Fn(&V) -> V,
709
0
        K: 'g,
710
    {
711
0
        self.update_or_insert_with(key, update, || value, guard)
712
0
    }
713
714
    /// Updates an existing entry or inserts a default value computed from a closure.
715
    ///
716
    /// If the value for the specified `key` is present, the new value is computed and stored the
717
    /// using the provided update function, and the new value is returned. Otherwise, the value
718
    /// computed by `f` is inserted into the map, and a reference to the newly inserted value is
719
    /// returned.
720
    ///
721
    /// See [`HashMap::update`] for details about how atomic updates are performed.
722
    ///
723
    /// # Examples
724
    ///
725
    /// ```
726
    /// use papaya::HashMap;
727
    ///
728
    /// let map = HashMap::new();
729
    /// assert_eq!(*map.pin().update_or_insert_with("a", |i| i + 1, || 0), 0);
730
    /// assert_eq!(*map.pin().update_or_insert_with("a", |i| i + 1, || 0), 1);
731
    /// ```
732
    #[inline]
733
0
    pub fn update_or_insert_with<'g, U, F>(
734
0
        &self,
735
0
        key: K,
736
0
        update: U,
737
0
        f: F,
738
0
        guard: &'g impl Guard,
739
0
    ) -> &'g V
740
0
    where
741
0
        F: FnOnce() -> V,
742
0
        U: Fn(&V) -> V,
743
0
        K: 'g,
744
    {
745
0
        self.raw
746
0
            .update_or_insert_with(key, update, f, self.raw.verify(guard))
747
0
    }
748
749
    /// Updates an entry with a compare-and-swap (CAS) function.
750
    ///
751
    /// This method allows you to perform complex operations on the map atomically. The `compute`
752
    /// closure is given the current state of the entry and returns the operation that should be
753
    /// performed. The operation is applied atomically only if the state of the entry remains the same,
754
    /// meaning it is not concurrently modified in any way.
755
    ///
756
    /// Note that the `compute` function should be pure as it may be called multiple times, and
757
    /// the output for a given entry may be memoized across retries.
758
    ///
759
    /// In most cases you can avoid this method and instead use a higher-level atomic operation.
760
    /// See the [crate-level documentation](crate#atomic-operations) for details.
761
    ///
762
    /// # Examples
763
    ///
764
    /// ```rust
765
    /// use papaya::{HashMap, Operation, Compute};
766
    ///
767
    /// let map = HashMap::new();
768
    /// let map = map.pin();
769
    ///
770
    /// let compute = |entry| match entry {
771
    ///     // Remove the value if it is even.
772
    ///     Some((_key, value)) if value % 2 == 0 => {
773
    ///         Operation::Remove
774
    ///     }
775
    ///
776
    ///     // Increment the value if it is odd.
777
    ///     Some((_key, value)) => {
778
    ///         Operation::Insert(value + 1)
779
    ///     }
780
    ///
781
    ///     // Do nothing if the key does not exist
782
    ///     None => Operation::Abort(()),
783
    /// };
784
    ///
785
    /// assert_eq!(map.compute('A', compute), Compute::Aborted(()));
786
    ///
787
    /// map.insert('A', 1);
788
    /// assert_eq!(map.compute('A', compute), Compute::Updated {
789
    ///     old: (&'A', &1),
790
    ///     new: (&'A', &2),
791
    /// });
792
    /// assert_eq!(map.compute('A', compute), Compute::Removed(&'A', &2));
793
    /// ```
794
    #[inline]
795
0
    pub fn compute<'g, F, T>(
796
0
        &self,
797
0
        key: K,
798
0
        compute: F,
799
0
        guard: &'g impl Guard,
800
0
    ) -> Compute<'g, K, V, T>
801
0
    where
802
0
        F: FnMut(Option<(&'g K, &'g V)>) -> Operation<V, T>,
803
    {
804
0
        self.raw.compute(key, compute, self.raw.verify(guard))
805
0
    }
806
807
    /// Removes a key from the map, returning the value at the key if the key
808
    /// was previously in the map.
809
    ///
810
    /// The key may be any borrowed form of the map's key type, but
811
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
812
    /// the key type.
813
    ///
814
    /// # Examples
815
    ///
816
    /// ```
817
    /// use papaya::HashMap;
818
    ///
819
    /// let map = HashMap::new();
820
    /// map.pin().insert(1, "a");
821
    /// assert_eq!(map.pin().remove(&1), Some(&"a"));
822
    /// assert_eq!(map.pin().remove(&1), None);
823
    /// ```
824
    #[inline]
825
0
    pub fn remove<'g, Q>(&self, key: &Q, guard: &'g impl Guard) -> Option<&'g V>
826
0
    where
827
0
        K: 'g,
828
0
        Q: Equivalent<K> + Hash + ?Sized,
829
    {
830
0
        match self.raw.remove(key, self.raw.verify(guard)) {
831
0
            Some((_, value)) => Some(value),
832
0
            None => None,
833
        }
834
0
    }
835
836
    /// Removes a key from the map, returning the stored key and value if the
837
    /// key was previously in the map.
838
    ///
839
    /// The key may be any borrowed form of the map's key type, but
840
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
841
    /// the key type.
842
    ///
843
    /// # Examples
844
    ///
845
    /// ```
846
    /// use papaya::HashMap;
847
    ///
848
    /// let map = HashMap::new();
849
    /// map.pin().insert(1, "a");
850
    /// assert_eq!(map.pin().get(&1), Some(&"a"));
851
    /// assert_eq!(map.pin().remove_entry(&1), Some((&1, &"a")));
852
    /// assert_eq!(map.pin().remove(&1), None);
853
    /// ```
854
    #[inline]
855
0
    pub fn remove_entry<'g, Q>(&self, key: &Q, guard: &'g impl Guard) -> Option<(&'g K, &'g V)>
856
0
    where
857
0
        K: 'g,
858
0
        Q: Equivalent<K> + Hash + ?Sized,
859
    {
860
0
        self.raw.remove(key, self.raw.verify(guard))
861
0
    }
862
863
    /// Conditionally removes a key from the map based on the provided closure.
864
    ///
865
    /// If the key is found in the map and the closure returns `true` given the key and its value,
866
    /// the key and value are returned successfully. Note that the returned entry is guaranteed to
867
    /// be the same entry that the closure returned `true` for. However, the closure returning `true`
868
    /// does not guarantee that the entry is removed in the presence of concurrent modifications.
869
    ///
870
    /// If the key is not found in the map, `Ok(None)` is returned.
871
    ///
872
    /// If the closure returns `false`, an error is returned containing the entry provided to the closure.
873
    ///
874
    /// # Examples
875
    ///
876
    /// ```
877
    /// use papaya::HashMap;
878
    ///
879
    /// let map = HashMap::new();
880
    /// map.pin().insert(1, "a");
881
    ///
882
    /// assert_eq!(map.pin().remove_if(&1, |k, v| *v == "b"), Err((&1, &"a")));
883
    /// assert_eq!(map.pin().get(&1), Some(&"a"));
884
    /// assert_eq!(map.pin().remove_if(&1, |k, v| *v == "a"), Ok(Some((&1, &"a"))));
885
    /// assert_eq!(map.pin().remove_if(&1, |_, _| true), Ok(None));
886
    /// ```
887
    #[inline]
888
0
    pub fn remove_if<'g, Q, F>(
889
0
        &self,
890
0
        key: &Q,
891
0
        should_remove: F,
892
0
        guard: &'g impl Guard,
893
0
    ) -> Result<Option<(&'g K, &'g V)>, (&'g K, &'g V)>
894
0
    where
895
0
        Q: Equivalent<K> + Hash + ?Sized,
896
0
        F: FnMut(&K, &V) -> bool,
897
    {
898
0
        self.raw
899
0
            .remove_if(key, should_remove, self.raw.verify(guard))
900
0
    }
901
902
    /// Tries to reserve capacity for `additional` more elements to be inserted
903
    /// in the `HashMap`.
904
    ///
905
    /// After calling this method, the table should be able to hold at least `capacity` elements
906
    /// before resizing. However, the capacity is an estimate, and the table may prematurely resize
907
    /// due to poor hash distribution. The collection may also reserve more space to avoid frequent
908
    /// reallocations.
909
    ///
910
    /// # Panics
911
    ///
912
    /// Panics if the new allocation size overflows `usize`.
913
    ///
914
    /// # Examples
915
    ///
916
    /// ```
917
    /// use papaya::HashMap;
918
    ///
919
    /// let map: HashMap<&str, i32> = HashMap::new();
920
    /// map.pin().reserve(10);
921
    /// ```
922
    #[inline]
923
0
    pub fn reserve(&self, additional: usize, guard: &impl Guard) {
924
0
        self.raw.reserve(additional, self.raw.verify(guard))
925
0
    }
926
927
    /// Clears the map, removing all key-value pairs.
928
    ///
929
    /// Note that this method will block until any in-progress resizes are
930
    /// completed before proceeding. See the [consistency](crate#consistency)
931
    /// section for details.
932
    ///
933
    /// # Examples
934
    ///
935
    /// ```
936
    /// use papaya::HashMap;
937
    ///
938
    /// let map = HashMap::new();
939
    ///
940
    /// map.pin().insert(1, "a");
941
    /// map.pin().clear();
942
    /// assert!(map.pin().is_empty());
943
    /// ```
944
    #[inline]
945
0
    pub fn clear(&self, guard: &impl Guard) {
946
0
        self.raw.clear(self.raw.verify(guard))
947
0
    }
948
949
    /// Retains only the elements specified by the predicate.
950
    ///
951
    /// In other words, remove all pairs `(k, v)` for which `f(&k, &v)` returns `false`.
952
    /// The elements are visited in unsorted (and unspecified) order.
953
    ///
954
    /// Note the function may be called more than once for a given key if its value is
955
    /// concurrently modified during removal.
956
    ///
957
    /// Additionally, this method will block until any in-progress resizes are
958
    /// completed before proceeding. See the [consistency](crate#consistency)
959
    /// section for details.
960
    ///
961
    /// # Examples
962
    ///
963
    /// ```
964
    /// use papaya::HashMap;
965
    ///
966
    /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x * 10)).collect();
967
    /// map.pin().retain(|&k, _| k % 2 == 0);
968
    /// assert_eq!(map.len(), 4);
969
    /// ```
970
    #[inline]
971
0
    pub fn retain<F>(&self, f: F, guard: &impl Guard)
972
0
    where
973
0
        F: FnMut(&K, &V) -> bool,
974
    {
975
0
        self.raw.retain(f, self.raw.verify(guard))
976
0
    }
977
978
    /// An iterator visiting all key-value pairs in arbitrary order.
979
    /// The iterator element type is `(&K, &V)`.
980
    ///
981
    /// Note that this method will block until any in-progress resizes are
982
    /// completed before proceeding. See the [consistency](crate#consistency)
983
    /// section for details.
984
    ///
985
    /// # Examples
986
    ///
987
    /// ```
988
    /// use papaya::HashMap;
989
    ///
990
    /// let map = HashMap::from([
991
    ///     ("a", 1),
992
    ///     ("b", 2),
993
    ///     ("c", 3),
994
    /// ]);
995
    ///
996
    /// for (key, val) in map.pin().iter() {
997
    ///     println!("key: {key} val: {val}");
998
    /// }
999
    #[inline]
1000
0
    pub fn iter<'g, G>(&self, guard: &'g G) -> Iter<'g, K, V, G>
1001
0
    where
1002
0
        G: Guard,
1003
    {
1004
0
        Iter {
1005
0
            raw: self.raw.iter(self.raw.verify(guard)),
1006
0
        }
1007
0
    }
1008
1009
    /// An iterator visiting all keys in arbitrary order.
1010
    /// The iterator element type is `&K`.
1011
    ///
1012
    /// Note that this method will block until any in-progress resizes are
1013
    /// completed before proceeding. See the [consistency](crate#consistency)
1014
    /// section for details.
1015
    ///
1016
    /// # Examples
1017
    ///
1018
    /// ```
1019
    /// use papaya::HashMap;
1020
    ///
1021
    /// let map = HashMap::from([
1022
    ///     ("a", 1),
1023
    ///     ("b", 2),
1024
    ///     ("c", 3),
1025
    /// ]);
1026
    ///
1027
    /// for key in map.pin().keys() {
1028
    ///     println!("{key}");
1029
    /// }
1030
    /// ```
1031
    #[inline]
1032
0
    pub fn keys<'g, G>(&self, guard: &'g G) -> Keys<'g, K, V, G>
1033
0
    where
1034
0
        G: Guard,
1035
    {
1036
0
        Keys {
1037
0
            iter: self.iter(guard),
1038
0
        }
1039
0
    }
1040
1041
    /// An iterator visiting all values in arbitrary order.
1042
    /// The iterator element type is `&V`.
1043
    ///
1044
    /// Note that this method will block until any in-progress resizes are
1045
    /// completed before proceeding. See the [consistency](crate#consistency)
1046
    /// section for details.
1047
    ///
1048
    /// # Examples
1049
    ///
1050
    /// ```
1051
    /// use papaya::HashMap;
1052
    ///
1053
    /// let map = HashMap::from([
1054
    ///     ("a", 1),
1055
    ///     ("b", 2),
1056
    ///     ("c", 3),
1057
    /// ]);
1058
    ///
1059
    /// for value in map.pin().values() {
1060
    ///     println!("{value}");
1061
    /// }
1062
    /// ```
1063
    #[inline]
1064
0
    pub fn values<'g, G>(&self, guard: &'g G) -> Values<'g, K, V, G>
1065
0
    where
1066
0
        G: Guard,
1067
    {
1068
0
        Values {
1069
0
            iter: self.iter(guard),
1070
0
        }
1071
0
    }
1072
}
1073
1074
/// An operation to perform on given entry in a [`HashMap`].
1075
///
1076
/// See [`HashMap::compute`] for details.
1077
#[derive(Debug, PartialEq, Eq)]
1078
pub enum Operation<V, T> {
1079
    /// Insert the given value.
1080
    Insert(V),
1081
1082
    /// Remove the entry from the map.
1083
    Remove,
1084
1085
    /// Abort the operation with the given value.
1086
    Abort(T),
1087
}
1088
1089
/// The result of a [`compute`](HashMap::compute) operation.
1090
///
1091
/// Contains information about the [`Operation`] that was performed.
1092
#[derive(Debug, PartialEq, Eq)]
1093
pub enum Compute<'g, K, V, T> {
1094
    /// The given entry was inserted.
1095
    Inserted(&'g K, &'g V),
1096
1097
    /// The entry was updated.
1098
    Updated {
1099
        /// The entry that was replaced.
1100
        old: (&'g K, &'g V),
1101
1102
        /// The entry that was inserted.
1103
        new: (&'g K, &'g V),
1104
    },
1105
1106
    /// The given entry was removed.
1107
    Removed(&'g K, &'g V),
1108
1109
    /// The operation was aborted with the given value.
1110
    Aborted(T),
1111
}
1112
1113
/// An error returned by [`try_insert`](HashMap::try_insert) when the key already exists.
1114
///
1115
/// Contains the existing value, and the value that was not inserted.
1116
#[derive(Debug, PartialEq, Eq)]
1117
pub struct OccupiedError<'a, V: 'a> {
1118
    /// The value in the map that was already present.
1119
    pub current: &'a V,
1120
    /// The value which was not inserted, because the entry was already occupied.
1121
    pub not_inserted: V,
1122
}
1123
1124
impl<K, V, S> PartialEq for HashMap<K, V, S>
1125
where
1126
    K: Hash + Eq,
1127
    V: PartialEq,
1128
    S: BuildHasher,
1129
{
1130
0
    fn eq(&self, other: &Self) -> bool {
1131
0
        if self.len() != other.len() {
1132
0
            return false;
1133
0
        }
1134
1135
0
        let (guard1, guard2) = (&self.guard(), &other.guard());
1136
1137
0
        let mut iter = self.iter(guard1);
1138
0
        iter.all(|(key, value)| other.get(key, guard2).is_some_and(|v| *value == *v))
1139
0
    }
1140
}
1141
1142
impl<K, V, S> Eq for HashMap<K, V, S>
1143
where
1144
    K: Hash + Eq,
1145
    V: Eq,
1146
    S: BuildHasher,
1147
{
1148
}
1149
1150
impl<K, V, S> fmt::Debug for HashMap<K, V, S>
1151
where
1152
    K: Hash + Eq + fmt::Debug,
1153
    V: fmt::Debug,
1154
    S: BuildHasher,
1155
{
1156
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1157
0
        let guard = self.guard();
1158
0
        f.debug_map().entries(self.iter(&guard)).finish()
1159
0
    }
1160
}
1161
1162
impl<K, V, S> Extend<(K, V)> for &HashMap<K, V, S>
1163
where
1164
    K: Hash + Eq,
1165
    S: BuildHasher,
1166
{
1167
0
    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
1168
        // from `hashbrown::HashMap::extend`:
1169
        // Keys may be already present or show multiple times in the iterator.
1170
        // Reserve the entire hint lower bound if the map is empty.
1171
        // Otherwise reserve half the hint (rounded up), so the map
1172
        // will only resize twice in the worst case.
1173
0
        let iter = iter.into_iter();
1174
0
        let reserve = if self.is_empty() {
1175
0
            iter.size_hint().0
1176
        } else {
1177
0
            (iter.size_hint().0 + 1) / 2
1178
        };
1179
1180
0
        let guard = self.guard();
1181
0
        self.reserve(reserve, &guard);
1182
1183
0
        for (key, value) in iter {
1184
0
            self.insert(key, value, &guard);
1185
0
        }
1186
0
    }
1187
}
1188
1189
impl<'a, K, V, S> Extend<(&'a K, &'a V)> for &HashMap<K, V, S>
1190
where
1191
    K: Copy + Hash + Eq,
1192
    V: Copy,
1193
    S: BuildHasher,
1194
{
1195
0
    fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
1196
0
        self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
1197
0
    }
1198
}
1199
1200
impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState>
1201
where
1202
    K: Hash + Eq,
1203
{
1204
0
    fn from(arr: [(K, V); N]) -> Self {
1205
0
        HashMap::from_iter(arr)
1206
0
    }
1207
}
1208
1209
impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>
1210
where
1211
    K: Hash + Eq,
1212
    S: BuildHasher + Default,
1213
{
1214
0
    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
1215
0
        let mut iter = iter.into_iter();
1216
1217
0
        if let Some((key, value)) = iter.next() {
1218
0
            let (lower, _) = iter.size_hint();
1219
0
            let map = HashMap::with_capacity_and_hasher(lower.saturating_add(1), S::default());
1220
1221
            // Ideally we could use an unprotected guard here. However, `insert`
1222
            // returns references to values that were replaced and retired, so
1223
            // we need a "real" guard. A `raw_insert` method that strictly returns
1224
            // pointers would fix this.
1225
            {
1226
0
                let map = map.pin();
1227
0
                map.insert(key, value);
1228
0
                for (key, value) in iter {
1229
0
                    map.insert(key, value);
1230
0
                }
1231
            }
1232
1233
0
            map
1234
        } else {
1235
0
            Self::default()
1236
        }
1237
0
    }
1238
}
1239
1240
impl<K, V, S> Clone for HashMap<K, V, S>
1241
where
1242
    K: Clone + Hash + Eq,
1243
    V: Clone,
1244
    S: BuildHasher + Clone,
1245
{
1246
0
    fn clone(&self) -> HashMap<K, V, S> {
1247
0
        let other = HashMap::builder()
1248
0
            .capacity(self.len())
1249
0
            .hasher(self.raw.hasher.clone())
1250
0
            .collector(seize::Collector::new())
1251
0
            .build();
1252
1253
        {
1254
0
            let (guard1, guard2) = (&self.guard(), &other.guard());
1255
0
            for (key, value) in self.iter(guard1) {
1256
0
                other.insert(key.clone(), value.clone(), guard2);
1257
0
            }
1258
        }
1259
1260
0
        other
1261
0
    }
1262
}
1263
1264
/// A pinned reference to a [`HashMap`].
1265
///
1266
/// This type is created with [`HashMap::pin`] and can be used to easily access a [`HashMap`]
1267
/// without explicitly managing a guard. See the [crate-level documentation](crate#usage) for details.
1268
pub struct HashMapRef<'map, K, V, S, G> {
1269
    guard: MapGuard<G>,
1270
    map: &'map HashMap<K, V, S>,
1271
}
1272
1273
impl<'map, K, V, S, G> HashMapRef<'map, K, V, S, G>
1274
where
1275
    K: Hash + Eq,
1276
    S: BuildHasher,
1277
    G: Guard,
1278
{
1279
    /// Returns a reference to the inner [`HashMap`].
1280
    #[inline]
1281
0
    pub fn map(&self) -> &'map HashMap<K, V, S> {
1282
0
        self.map
1283
0
    }
1284
1285
    /// Returns the number of entries in the map.
1286
    ///
1287
    /// See [`HashMap::len`] for details.
1288
    #[inline]
1289
0
    pub fn len(&self) -> usize {
1290
0
        self.map.raw.len()
1291
0
    }
1292
1293
    /// Returns `true` if the map is empty. Otherwise returns `false`.
1294
    ///
1295
    /// See [`HashMap::is_empty`] for details.
1296
    #[inline]
1297
0
    pub fn is_empty(&self) -> bool {
1298
0
        self.len() == 0
1299
0
    }
1300
1301
    /// Returns `true` if the map contains a value for the specified key.
1302
    ///
1303
    /// See [`HashMap::contains_key`] for details.
1304
    #[inline]
1305
0
    pub fn contains_key<Q>(&self, key: &Q) -> bool
1306
0
    where
1307
0
        Q: Equivalent<K> + Hash + ?Sized,
1308
    {
1309
0
        self.get(key).is_some()
1310
0
    }
1311
1312
    /// Returns a reference to the value corresponding to the key.
1313
    ///
1314
    /// See [`HashMap::get`] for details.
1315
    #[inline]
1316
0
    pub fn get<Q>(&self, key: &Q) -> Option<&V>
1317
0
    where
1318
0
        Q: Equivalent<K> + Hash + ?Sized,
1319
    {
1320
0
        match self.map.raw.get(key, &self.guard) {
1321
0
            Some((_, v)) => Some(v),
1322
0
            None => None,
1323
        }
1324
0
    }
1325
1326
    /// Returns the key-value pair corresponding to the supplied key.
1327
    ///
1328
    /// See [`HashMap::get_key_value`] for details.
1329
    #[inline]
1330
0
    pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
1331
0
    where
1332
0
        Q: Equivalent<K> + Hash + ?Sized,
1333
    {
1334
0
        self.map.raw.get(key, &self.guard)
1335
0
    }
1336
1337
    /// Inserts a key-value pair into the map.
1338
    ///
1339
    /// See [`HashMap::insert`] for details.
1340
    #[inline]
1341
0
    pub fn insert(&self, key: K, value: V) -> Option<&V> {
1342
0
        match self.map.raw.insert(key, value, true, &self.guard) {
1343
0
            InsertResult::Inserted(_) => None,
1344
0
            InsertResult::Replaced(value) => Some(value),
1345
0
            InsertResult::Error { .. } => unreachable!(),
1346
        }
1347
0
    }
1348
1349
    /// Tries to insert a key-value pair into the map, and returns
1350
    /// a reference to the value that was inserted.
1351
    ///
1352
    /// See [`HashMap::try_insert`] for details.
1353
    #[inline]
1354
0
    pub fn try_insert(&self, key: K, value: V) -> Result<&V, OccupiedError<'_, V>> {
1355
0
        match self.map.raw.insert(key, value, false, &self.guard) {
1356
0
            InsertResult::Inserted(value) => Ok(value),
1357
            InsertResult::Error {
1358
0
                current,
1359
0
                not_inserted,
1360
0
            } => Err(OccupiedError {
1361
0
                current,
1362
0
                not_inserted,
1363
0
            }),
1364
0
            InsertResult::Replaced(_) => unreachable!(),
1365
        }
1366
0
    }
1367
1368
    /// Tries to insert a key and value computed from a closure into the map,
1369
    /// and returns a reference to the value that was inserted.
1370
    ///
1371
    /// See [`HashMap::try_insert_with`] for details.
1372
    #[inline]
1373
0
    pub fn try_insert_with<F>(&self, key: K, f: F) -> Result<&V, &V>
1374
0
    where
1375
0
        F: FnOnce() -> V,
1376
    {
1377
0
        self.map.raw.try_insert_with(key, f, &self.guard)
1378
0
    }
1379
1380
    /// Returns a reference to the value corresponding to the key, or inserts a default value.
1381
    ///
1382
    /// See [`HashMap::get_or_insert`] for details.
1383
    #[inline]
1384
0
    pub fn get_or_insert(&self, key: K, value: V) -> &V {
1385
        // Note that we use `try_insert` instead of `compute` or `get_or_insert_with` here, as it
1386
        // allows us to avoid the closure indirection.
1387
0
        match self.try_insert(key, value) {
1388
0
            Ok(inserted) => inserted,
1389
0
            Err(OccupiedError { current, .. }) => current,
1390
        }
1391
0
    }
1392
1393
    /// Returns a reference to the value corresponding to the key, or inserts a default value
1394
    /// computed from a closure.
1395
    ///
1396
    /// See [`HashMap::get_or_insert_with`] for details.
1397
    #[inline]
1398
0
    pub fn get_or_insert_with<F>(&self, key: K, f: F) -> &V
1399
0
    where
1400
0
        F: FnOnce() -> V,
1401
    {
1402
0
        self.map.raw.get_or_insert_with(key, f, &self.guard)
1403
0
    }
1404
1405
    /// Updates an existing entry atomically.
1406
    ///
1407
    /// See [`HashMap::update`] for details.
1408
    #[inline]
1409
0
    pub fn update<F>(&self, key: K, update: F) -> Option<&V>
1410
0
    where
1411
0
        F: Fn(&V) -> V,
1412
    {
1413
0
        self.map.raw.update(key, update, &self.guard)
1414
0
    }
1415
1416
    /// Updates an existing entry or inserts a default value.
1417
    ///
1418
    /// See [`HashMap::update_or_insert`] for details.
1419
    #[inline]
1420
0
    pub fn update_or_insert<F>(&self, key: K, update: F, value: V) -> &V
1421
0
    where
1422
0
        F: Fn(&V) -> V,
1423
    {
1424
0
        self.update_or_insert_with(key, update, || value)
1425
0
    }
1426
1427
    /// Updates an existing entry or inserts a default value computed from a closure.
1428
    ///
1429
    /// See [`HashMap::update_or_insert_with`] for details.
1430
    #[inline]
1431
0
    pub fn update_or_insert_with<U, F>(&self, key: K, update: U, f: F) -> &V
1432
0
    where
1433
0
        F: FnOnce() -> V,
1434
0
        U: Fn(&V) -> V,
1435
    {
1436
0
        self.map
1437
0
            .raw
1438
0
            .update_or_insert_with(key, update, f, &self.guard)
1439
0
    }
1440
1441
    // Updates an entry with a compare-and-swap (CAS) function.
1442
    //
1443
    /// See [`HashMap::compute`] for details.
1444
    #[inline]
1445
0
    pub fn compute<'g, F, T>(&'g self, key: K, compute: F) -> Compute<'g, K, V, T>
1446
0
    where
1447
0
        F: FnMut(Option<(&'g K, &'g V)>) -> Operation<V, T>,
1448
    {
1449
0
        self.map.raw.compute(key, compute, &self.guard)
1450
0
    }
1451
1452
    /// Removes a key from the map, returning the value at the key if the key
1453
    /// was previously in the map.
1454
    ///
1455
    /// See [`HashMap::remove`] for details.
1456
    #[inline]
1457
0
    pub fn remove<Q>(&self, key: &Q) -> Option<&V>
1458
0
    where
1459
0
        Q: Equivalent<K> + Hash + ?Sized,
1460
    {
1461
0
        match self.map.raw.remove(key, &self.guard) {
1462
0
            Some((_, value)) => Some(value),
1463
0
            None => None,
1464
        }
1465
0
    }
1466
1467
    /// Removes a key from the map, returning the stored key and value if the
1468
    /// key was previously in the map.
1469
    ///
1470
    /// See [`HashMap::remove_entry`] for details.
1471
    #[inline]
1472
0
    pub fn remove_entry<Q>(&self, key: &Q) -> Option<(&K, &V)>
1473
0
    where
1474
0
        Q: Equivalent<K> + Hash + ?Sized,
1475
    {
1476
0
        self.map.raw.remove(key, &self.guard)
1477
0
    }
1478
1479
    /// Conditionally removes a key from the map based on the provided closure.
1480
    ///
1481
    /// See [`HashMap::remove_if`] for details.
1482
    #[inline]
1483
0
    pub fn remove_if<Q, F>(&self, key: &Q, should_remove: F) -> Result<Option<(&K, &V)>, (&K, &V)>
1484
0
    where
1485
0
        Q: Equivalent<K> + Hash + ?Sized,
1486
0
        F: FnMut(&K, &V) -> bool,
1487
    {
1488
0
        self.map.raw.remove_if(key, should_remove, &self.guard)
1489
0
    }
1490
1491
    /// Clears the map, removing all key-value pairs.
1492
    ///
1493
    /// See [`HashMap::clear`] for details.
1494
    #[inline]
1495
0
    pub fn clear(&self) {
1496
0
        self.map.raw.clear(&self.guard)
1497
0
    }
1498
1499
    /// Retains only the elements specified by the predicate.
1500
    ///
1501
    /// See [`HashMap::retain`] for details.
1502
    #[inline]
1503
0
    pub fn retain<F>(&mut self, f: F)
1504
0
    where
1505
0
        F: FnMut(&K, &V) -> bool,
1506
    {
1507
0
        self.map.raw.retain(f, &self.guard)
1508
0
    }
1509
1510
    /// Tries to reserve capacity for `additional` more elements to be inserted
1511
    /// in the map.
1512
    ///
1513
    /// See [`HashMap::reserve`] for details.
1514
    #[inline]
1515
0
    pub fn reserve(&self, additional: usize) {
1516
0
        self.map.raw.reserve(additional, &self.guard)
1517
0
    }
1518
1519
    /// An iterator visiting all key-value pairs in arbitrary order.
1520
    /// The iterator element type is `(&K, &V)`.
1521
    ///
1522
    /// See [`HashMap::iter`] for details.
1523
    #[inline]
1524
0
    pub fn iter(&self) -> Iter<'_, K, V, G> {
1525
0
        Iter {
1526
0
            raw: self.map.raw.iter(&self.guard),
1527
0
        }
1528
0
    }
1529
1530
    /// An iterator visiting all keys in arbitrary order.
1531
    /// The iterator element type is `&K`.
1532
    ///
1533
    /// See [`HashMap::keys`] for details.
1534
    #[inline]
1535
0
    pub fn keys(&self) -> Keys<'_, K, V, G> {
1536
0
        Keys { iter: self.iter() }
1537
0
    }
1538
1539
    /// An iterator visiting all values in arbitrary order.
1540
    /// The iterator element type is `&V`.
1541
    ///
1542
    /// See [`HashMap::values`] for details.
1543
    #[inline]
1544
0
    pub fn values(&self) -> Values<'_, K, V, G> {
1545
0
        Values { iter: self.iter() }
1546
0
    }
1547
}
1548
1549
impl<K, V, S, G> fmt::Debug for HashMapRef<'_, K, V, S, G>
1550
where
1551
    K: Hash + Eq + fmt::Debug,
1552
    V: fmt::Debug,
1553
    S: BuildHasher,
1554
    G: Guard,
1555
{
1556
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1557
0
        f.debug_map().entries(self.iter()).finish()
1558
0
    }
1559
}
1560
1561
impl<'a, K, V, S, G> IntoIterator for &'a HashMapRef<'_, K, V, S, G>
1562
where
1563
    K: Hash + Eq,
1564
    S: BuildHasher,
1565
    G: Guard,
1566
{
1567
    type Item = (&'a K, &'a V);
1568
    type IntoIter = Iter<'a, K, V, G>;
1569
1570
0
    fn into_iter(self) -> Self::IntoIter {
1571
0
        self.iter()
1572
0
    }
1573
}
1574
1575
/// An iterator over a map's entries.
1576
///
1577
/// This struct is created by the [`iter`](HashMap::iter) method on [`HashMap`]. See its documentation for details.
1578
pub struct Iter<'g, K, V, G> {
1579
    raw: raw::Iter<'g, K, V, MapGuard<G>>,
1580
}
1581
1582
impl<'g, K: 'g, V: 'g, G> Iterator for Iter<'g, K, V, G>
1583
where
1584
    G: Guard,
1585
{
1586
    type Item = (&'g K, &'g V);
1587
1588
    #[inline]
1589
0
    fn next(&mut self) -> Option<Self::Item> {
1590
0
        self.raw.next()
1591
0
    }
1592
}
1593
1594
impl<K, V, G> fmt::Debug for Iter<'_, K, V, G>
1595
where
1596
    K: fmt::Debug,
1597
    V: fmt::Debug,
1598
    G: Guard,
1599
{
1600
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1601
0
        f.debug_list()
1602
0
            .entries(Iter {
1603
0
                raw: self.raw.clone(),
1604
0
            })
1605
0
            .finish()
1606
0
    }
1607
}
1608
1609
/// An iterator over a map's keys.
1610
///
1611
/// This struct is created by the [`keys`](HashMap::keys) method on [`HashMap`]. See its documentation for details.
1612
pub struct Keys<'g, K, V, G> {
1613
    iter: Iter<'g, K, V, G>,
1614
}
1615
1616
impl<'g, K: 'g, V: 'g, G> Iterator for Keys<'g, K, V, G>
1617
where
1618
    G: Guard,
1619
{
1620
    type Item = &'g K;
1621
1622
    #[inline]
1623
0
    fn next(&mut self) -> Option<Self::Item> {
1624
0
        let (key, _) = self.iter.next()?;
1625
0
        Some(key)
1626
0
    }
1627
}
1628
1629
impl<K, V, G> fmt::Debug for Keys<'_, K, V, G>
1630
where
1631
    K: fmt::Debug,
1632
    V: fmt::Debug,
1633
    G: Guard,
1634
{
1635
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1636
0
        f.debug_tuple("Keys").field(&self.iter).finish()
1637
0
    }
1638
}
1639
1640
/// An iterator over a map's values.
1641
///
1642
/// This struct is created by the [`values`](HashMap::values) method on [`HashMap`]. See its documentation for details.
1643
pub struct Values<'g, K, V, G> {
1644
    iter: Iter<'g, K, V, G>,
1645
}
1646
1647
impl<'g, K: 'g, V: 'g, G> Iterator for Values<'g, K, V, G>
1648
where
1649
    G: Guard,
1650
{
1651
    type Item = &'g V;
1652
1653
    #[inline]
1654
0
    fn next(&mut self) -> Option<Self::Item> {
1655
0
        let (_, value) = self.iter.next()?;
1656
0
        Some(value)
1657
0
    }
1658
}
1659
1660
impl<K, V, G> fmt::Debug for Values<'_, K, V, G>
1661
where
1662
    K: fmt::Debug,
1663
    V: fmt::Debug,
1664
    G: Guard,
1665
{
1666
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1667
0
        f.debug_tuple("Values").field(&self.iter).finish()
1668
0
    }
1669
}