hashbag/
lib.rs

1//! An unordered multiset/bag implementation backed by `HashMap`.
2//!
3//! A bag, unlike a set, allows duplicate values, and keeps track of how many
4//! duplicates each value holds. This type of collection is often referred to
5//! as an unordered multiset (see also C++'s [`std::unordered_multiset`]).
6//!
7//! This multiset/bag is implemented using a `HashMap<T, usize>` and so requires
8//! that the stored type implements `Hash + Eq`.
9//!
10//! For usage examples, see the primary type [`HashBag`].
11//!
12//! If you want to use a hash table with [amortized resizes](https://github.com/jonhoo/griddle/),
13//! set the `amortize` feature.
14//!
15//! (De)serialization via serde is also available with the `serde` feature.
16//! Deserialization note: if the incoming data contains two instances of `T` that are the same, the resulting `HashBag` will merge
17//! the counts of those instances.
18//!
19//!   [`std::unordered_multiset`]: http://www.cplusplus.com/reference/unordered_set/unordered_multiset/
20#![deny(missing_docs, missing_debug_implementations, unreachable_pub)]
21#![cfg_attr(doc, deny(rustdoc::broken_intra_doc_links))]
22#![warn(rust_2018_idioms)]
23
24#[cfg(feature = "amortize")]
25use griddle::HashMap;
26use std::borrow::Borrow;
27use std::collections::hash_map::RandomState;
28#[cfg(not(feature = "amortize"))]
29use std::collections::HashMap;
30use std::convert::TryFrom;
31use std::hash::{BuildHasher, Hash};
32
33#[cfg(feature = "serde")]
34mod serde;
35
36/// A hash bag implemented as a `HashMap` where the value is `usize`.
37///
38/// A bag, unlike a set, allows duplicate values, and keeps track of how many
39/// duplicates each value holds. This type of collection is often referred to
40/// as an unordered multiset.
41///
42/// As with the [`HashMap`] type, a `HashBag` requires that the elements
43/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
44/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
45/// it is important that the following property holds:
46///
47/// ```text
48/// k1 == k2 -> hash(k1) == hash(k2)
49/// ```
50///
51/// In other words, if two keys are equal, their hashes must be equal.
52///
53/// It is a logic error for an item to be modified in such a way that the
54/// item's hash, as determined by the [`Hash`] trait, or its equality, as
55/// determined by the [`Eq`] trait, changes while it is in the bag.
56///
57/// # Examples
58///
59/// ```
60/// use hashbag::HashBag;
61/// // Type inference lets us omit an explicit type signature (which
62/// // would be `HashBag<String>` in this example).
63/// let mut books = HashBag::new();
64///
65/// // Add some books.
66/// // Since we are a library, we have many copies.
67/// books.insert("A Dance With Dragons".to_string());
68/// books.insert("To Kill a Mockingbird".to_string());
69/// books.insert("To Kill a Mockingbird".to_string());
70/// books.insert("The Odyssey".to_string());
71/// books.insert("The Odyssey".to_string());
72/// books.insert("The Odyssey".to_string());
73/// books.insert("The Great Gatsby".to_string());
74/// books.insert("The Great Gatsby".to_string());
75/// books.insert("The Great Gatsby".to_string());
76/// books.insert("The Great Gatsby".to_string());
77///
78/// // When we count the number of books, duplicates are included.
79/// assert_eq!(books.len(), 10);
80///
81/// // Check for a specific one.
82/// if books.contains("The Winds of Winter") == 0 {
83///     println!("We have {} books, but The Winds of Winter ain't one.",
84///              books.len());
85/// }
86///
87/// // Remove a book.
88/// let had_copies = books.remove("The Odyssey");
89/// // Remove returns how many copies of that book we had.
90/// assert_eq!(had_copies, 3);
91///
92/// // Iterate over everything.
93/// // Duplicates will be listed multiple times.
94/// for book in &books {
95///     println!("{}", book);
96/// }
97///
98/// // Iterate over each distinct book.
99/// for (book, copies) in books.set_iter() {
100///     println!("{} ({} copies)", book, copies);
101/// }
102///
103/// // Extract the books and their counts.
104/// for (book, copies) in books {
105///     println!("{} ({} copies)", book, copies);
106/// }
107/// ```
108///
109/// The easiest way to use `HashBag` with a custom type is to derive
110/// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`], this will in the
111/// future be implied by [`Eq`].
112///
113/// ```
114/// use hashbag::HashBag;
115/// #[derive(Hash, Eq, PartialEq, Debug, Clone)]
116/// struct Viking {
117///     name: String,
118///     power: usize,
119/// }
120///
121/// let mut vikings = HashBag::new();
122///
123/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
124/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
125/// vikings.insert(Viking { name: "Olaf".to_string(), power: 4 });
126/// vikings.insert(Viking { name: "Olaf".to_string(), power: 5 });
127/// vikings.insert(Viking { name: "Harald".to_string(), power: 8 });
128///
129/// // Use derived implementation to print the vikings.
130/// // Notice that all duplicates are printed.
131/// for v in &vikings {
132///     println!("{:?}", v);
133/// }
134///
135/// // Since the derived implementation compares all the fields,
136/// // vikings that share a name but not a power are not duplicates.
137/// for (v, n) in vikings.set_iter() {
138///     println!("{:?} ({} of them!)", v, n);
139/// }
140///
141/// // HashBags themselves can also be compared for equality,
142/// // and will do so by considering both the values and their counts.
143/// let mut vikings2 = vikings.clone();
144/// assert_eq!(vikings, vikings2);
145/// let fallen = vikings.iter().next().unwrap();
146/// vikings2.remove(fallen);
147/// assert_ne!(vikings, vikings2);
148/// vikings2.insert(Viking { name: "Snorre".to_string(), power: 1 });
149/// assert_ne!(vikings, vikings2);
150/// ```
151///
152/// A `HashBag` with fixed list of elements can be initialized from an array:
153///
154/// ```
155/// use hashbag::HashBag;
156///
157/// let mut viking_names: HashBag<&'static str> =
158///     [ "Einar", "Olaf", "Harald" ].iter().cloned().collect();
159/// // use the values stored in the bag
160/// ```
161///
162/// You can also extend the bag easily:
163///
164/// ```
165/// use hashbag::HashBag;
166///
167/// let mut vikings: HashBag<String> = HashBag::new();
168/// vikings.extend(std::iter::once("Snorre".to_string()));
169/// assert_eq!(vikings.contains("Snorre"), 1);
170///
171/// // You can extend with many instances at once:
172/// vikings.extend(std::iter::once(("Snorre".to_string(), 4)));
173/// assert_eq!(vikings.contains("Snorre"), 5);
174///
175/// // Extension also works with reference iterators if the type is Clone:
176/// let einar = String::from("Einar");
177/// vikings.extend(std::iter::once(&einar));
178/// assert_eq!(vikings.contains(&einar), 1);
179///
180/// // And extend with many instances at once:
181/// vikings.extend(std::iter::once((&einar, 4)));
182/// assert_eq!(vikings.contains(&einar), 5);
183/// ```
184pub struct HashBag<T, S = RandomState> {
185    items: HashMap<T, usize, S>,
186    count: usize,
187}
188
189impl<T: Clone + Hash, S: Clone + BuildHasher> Clone for HashBag<T, S> {
190    fn clone(&self) -> Self {
191        Self {
192            items: self.items.clone(),
193            count: self.count,
194        }
195    }
196
197    fn clone_from(&mut self, source: &Self) {
198        self.items.clone_from(&source.items);
199        self.count = source.count;
200    }
201}
202
203impl<T: Hash + Eq> HashBag<T, RandomState> {
204    /// Creates an empty `HashBag`.
205    ///
206    /// The hash bag is initially created with a capacity of 0, so it will not allocate until it
207    /// is first inserted into.
208    ///
209    /// # Examples
210    ///
211    /// ```
212    /// use hashbag::HashBag;
213    /// let bag: HashBag<i32> = HashBag::new();
214    /// ```
215    #[inline]
216    pub fn new() -> HashBag<T, RandomState> {
217        Self::with_hasher(RandomState::new())
218    }
219
220    /// Creates an empty `HashBag` with the specified capacity.
221    ///
222    /// The hash bag will be able to hold at least `capacity` distinct values without
223    /// reallocating. If `capacity` is 0, the hash bag will not allocate.
224    ///
225    /// # Examples
226    ///
227    /// ```
228    /// use hashbag::HashBag;
229    /// let bag: HashBag<i32> = HashBag::with_capacity(10);
230    /// assert!(bag.capacity() >= 10);
231    /// ```
232    #[inline]
233    pub fn with_capacity(capacity: usize) -> HashBag<T, RandomState> {
234        Self::with_capacity_and_hasher(capacity, RandomState::new())
235    }
236}
237
238impl<T, S> HashBag<T, S> {
239    /// Returns the number of distinct values the bag can hold without reallocating.
240    ///
241    /// # Examples
242    ///
243    /// ```
244    /// use hashbag::HashBag;
245    /// let bag: HashBag<i32> = HashBag::with_capacity(100);
246    /// assert!(bag.capacity() >= 100);
247    /// ```
248    #[inline]
249    pub fn capacity(&self) -> usize {
250        self.items.capacity()
251    }
252
253    /// An iterator visiting all elements in arbitrary order.
254    ///
255    /// The iterator element type is `&'a T`.
256    /// Duplicates are yielded as many times as they appear in the bag.
257    ///
258    /// # Examples
259    ///
260    /// ```
261    /// use hashbag::HashBag;
262    /// let mut bag = HashBag::new();
263    /// bag.insert("a");
264    /// bag.insert("b");
265    /// bag.insert("b");
266    ///
267    /// // Will print in an arbitrary order.
268    /// // b will be printed twice.
269    /// for x in bag.iter() {
270    ///     println!("{}", x);
271    /// }
272    /// ```
273    #[inline]
274    pub fn iter(&self) -> Iter<'_, T> {
275        Iter::new(self.items.iter(), self.count)
276    }
277
278    /// An iterator visiting all distinct elements in arbitrary order.
279    ///
280    /// The iterator element type is `(&'a T, usize)`.
281    /// Duplicated values are yielded once along with a count of the number of occurrences.
282    ///
283    /// # Examples
284    ///
285    /// ```
286    /// use hashbag::HashBag;
287    /// let mut bag = HashBag::new();
288    /// bag.insert("a");
289    /// bag.insert("b");
290    /// bag.insert("b");
291    ///
292    /// // Will print in an arbitrary order.
293    /// for (x, n) in bag.set_iter() {
294    ///     println!("{} {}", x, n);
295    /// }
296    /// ```
297    #[inline]
298    pub fn set_iter(&self) -> SetIter<'_, T> {
299        SetIter(self.items.iter())
300    }
301
302    /// Returns the number of elements in the bag.
303    ///
304    /// Duplicates are counted.
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// use hashbag::HashBag;
310    ///
311    /// let mut bag = HashBag::new();
312    /// assert_eq!(bag.len(), 0);
313    /// bag.insert(1);
314    /// assert_eq!(bag.len(), 1);
315    /// bag.insert(1);
316    /// assert_eq!(bag.len(), 2);
317    /// ```
318    #[inline]
319    pub fn len(&self) -> usize {
320        self.count
321    }
322
323    /// Returns the number of elements in the bag.
324    ///
325    /// Duplicates are not counted.
326    ///
327    /// # Examples
328    ///
329    /// ```
330    /// use hashbag::HashBag;
331    ///
332    /// let mut bag = HashBag::new();
333    /// assert_eq!(bag.set_len(), 0);
334    /// bag.insert(1);
335    /// assert_eq!(bag.set_len(), 1);
336    /// bag.insert(1);
337    /// assert_eq!(bag.set_len(), 1);
338    /// ```
339    #[inline]
340    pub fn set_len(&self) -> usize {
341        self.items.len()
342    }
343
344    /// Returns `true` if the bag contains no elements.
345    ///
346    /// # Examples
347    ///
348    /// ```
349    /// use hashbag::HashBag;
350    ///
351    /// let mut bag = HashBag::new();
352    /// assert!(bag.is_empty());
353    /// bag.insert(1);
354    /// assert!(!bag.is_empty());
355    /// ```
356    #[inline]
357    pub fn is_empty(&self) -> bool {
358        self.count == 0
359    }
360
361    /// Clears the bag, returning all elements in an iterator.
362    ///
363    /// Duplicates appear only in the count yielded for each element.
364    ///
365    /// # Examples
366    ///
367    /// ```
368    /// use hashbag::HashBag;
369    ///
370    /// let mut bag: HashBag<_> = [1, 2, 3, 3].iter().cloned().collect();
371    /// assert!(!bag.is_empty());
372    ///
373    /// // prints
374    /// //   1 1
375    /// //   2 1
376    /// //   3 2
377    /// // in an arbitrary order
378    /// for (i, n) in bag.drain() {
379    ///     println!("{} {}", i, n);
380    /// }
381    ///
382    /// assert!(bag.is_empty());
383    /// ```
384    #[inline]
385    pub fn drain(&mut self) -> Drain<'_, T> {
386        self.count = 0;
387        Drain(self.items.drain())
388    }
389
390    /// Clears the bag, removing all values.
391    ///
392    /// # Examples
393    ///
394    /// ```
395    /// use hashbag::HashBag;
396    ///
397    /// let mut bag = HashBag::new();
398    /// bag.insert(1);
399    /// bag.clear();
400    /// assert!(bag.is_empty());
401    /// ```
402    #[inline]
403    pub fn clear(&mut self) {
404        self.count = 0;
405        self.items.clear();
406    }
407}
408
409impl<T, S> HashBag<T, S>
410where
411    T: Eq + Hash,
412    S: BuildHasher,
413{
414    /// Creates a new empty hash bag which will use the given hasher to hash
415    /// keys.
416    ///
417    /// The hash bag is also created with the default initial capacity.
418    ///
419    /// Warning: `hasher` is normally randomly generated, and
420    /// is designed to allow `HashBag`s to be resistant to attacks that
421    /// cause many collisions and very poor performance. Setting it
422    /// manually using this function can expose a DoS attack vector.
423    ///
424    /// # Examples
425    ///
426    /// ```
427    /// use hashbag::HashBag;
428    /// use std::collections::hash_map::RandomState;
429    ///
430    /// let s = RandomState::new();
431    /// let mut bag = HashBag::with_hasher(s);
432    /// bag.insert(2);
433    /// ```
434    #[inline]
435    pub fn with_hasher(hash_builder: S) -> HashBag<T, S> {
436        HashBag {
437            items: HashMap::with_hasher(hash_builder),
438            count: 0,
439        }
440    }
441
442    /// Creates an empty `HashBag` with the specified capacity, using
443    /// `hasher` to hash the keys.
444    ///
445    /// The hash bag will be able to hold at least `capacity` distinct values
446    /// without reallocating. If `capacity` is 0, the hash bag will not allocate.
447    ///
448    /// Warning: `hasher` is normally randomly generated, and
449    /// is designed to allow `HashBag`s to be resistant to attacks that
450    /// cause many collisions and very poor performance. Setting it
451    /// manually using this function can expose a DoS attack vector.
452    ///
453    /// # Examples
454    ///
455    /// ```
456    /// use hashbag::HashBag;
457    /// use std::collections::hash_map::RandomState;
458    ///
459    /// let s = RandomState::new();
460    /// let mut bag = HashBag::with_capacity_and_hasher(10, s);
461    /// bag.insert(1);
462    /// ```
463    #[inline]
464    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashBag<T, S> {
465        HashBag {
466            items: HashMap::with_capacity_and_hasher(capacity, hash_builder),
467            count: 0,
468        }
469    }
470
471    /// Returns a reference to the bag's [`BuildHasher`].
472    ///
473    /// # Examples
474    ///
475    /// ```
476    /// use hashbag::HashBag;
477    /// use std::collections::hash_map::RandomState;
478    ///
479    /// let hasher = RandomState::new();
480    /// let bag: HashBag<i32> = HashBag::with_hasher(hasher);
481    /// let hasher: &RandomState = bag.hasher();
482    /// ```
483    #[inline]
484    pub fn hasher(&self) -> &S {
485        self.items.hasher()
486    }
487
488    /// Reserves capacity for at least `additional` more distinct values
489    /// to be inserted in the `HashBag`. The collection may reserve more
490    /// space to avoid frequent reallocations.
491    ///
492    /// # Panics
493    ///
494    /// Panics if the new allocation size overflows `usize`.
495    ///
496    /// # Examples
497    ///
498    /// ```
499    /// use hashbag::HashBag;
500    /// let mut bag: HashBag<i32> = HashBag::new();
501    /// bag.reserve(10);
502    /// assert!(bag.capacity() >= 10);
503    /// ```
504    #[inline]
505    pub fn reserve(&mut self, additional: usize) {
506        self.items.reserve(additional)
507    }
508
509    /// Shrinks the capacity of the ba as much as possible. It will drop
510    /// down as much as possible while maintaining the internal rules
511    /// and possibly leaving some space in accordance with the resize policy.
512    ///
513    /// # Examples
514    ///
515    /// ```
516    /// use hashbag::HashBag;
517    ///
518    /// let mut bag = HashBag::with_capacity(100);
519    /// bag.insert(1);
520    /// bag.insert(2);
521    /// assert!(bag.capacity() >= 100);
522    /// bag.shrink_to_fit();
523    /// assert!(bag.capacity() >= 2);
524    /// ```
525    #[inline]
526    pub fn shrink_to_fit(&mut self) {
527        self.items.shrink_to_fit()
528    }
529
530    /// Returns the number of instances of `value` in the bag.
531    ///
532    /// The value may be any borrowed form of the bag's value type, but
533    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
534    /// the value type.
535    ///
536    /// # Examples
537    ///
538    /// ```
539    /// use hashbag::HashBag;
540    ///
541    /// let bag: HashBag<_> = [1, 2, 3, 3].iter().cloned().collect();
542    /// assert_eq!(bag.contains(&1), 1);
543    /// assert_eq!(bag.contains(&3), 2);
544    /// assert_eq!(bag.contains(&4), 0);
545    /// ```
546    #[inline]
547    pub fn contains<Q: ?Sized>(&self, value: &Q) -> usize
548    where
549        T: Borrow<Q>,
550        Q: Hash + Eq,
551    {
552        self.items.get(value).cloned().unwrap_or(0)
553    }
554
555    /// Returns a reference to the value in the bag, if any, that is equal to the given value,
556    /// along with its number of occurrences.
557    ///
558    /// The value may be any borrowed form of the bag's value type, but
559    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
560    /// the value type.
561    ///
562    /// # Examples
563    ///
564    /// ```
565    /// use hashbag::HashBag;
566    ///
567    /// let bag: HashBag<_> = [1, 2, 3, 3].iter().cloned().collect();
568    /// assert_eq!(bag.get(&2), Some((&2, 1)));
569    /// assert_eq!(bag.get(&3), Some((&3, 2)));
570    /// assert_eq!(bag.get(&4), None);
571    /// ```
572    #[inline]
573    pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<(&T, usize)>
574    where
575        T: Borrow<Q>,
576        Q: Hash + Eq,
577    {
578        self.items
579            .get_key_value(value)
580            .map(|(t, count)| (t, *count))
581    }
582
583    /// Gets a given value's corresponding entry in the bag for in-place manipulation.
584    ///
585    /// # Examples
586    ///
587    /// ```
588    /// use hashbag::HashBag;
589    ///
590    /// let mut bag: HashBag<char> = ['a'].iter().cloned().collect();
591    /// let entry = bag.entry('a').and_modify(|n| *n += 1).or_insert();
592    /// assert_eq!(bag.get(&'a'), Some((&'a', 2)));
593    /// let entry = bag.entry('b').and_modify(|n| *n += 1).or_insert();
594    /// assert_eq!(bag.get(&'b'), Some((&'b', 1)));
595    /// let entry = bag.entry('c').and_modify(|n| *n += 1).or_insert_many(7);
596    /// assert_eq!(bag.get(&'c'), Some((&'c', 7)));
597    /// ```
598    #[inline]
599    pub fn entry(&mut self, value: T) -> Entry<'_, T, S> {
600        Entry((
601            ForiegnEntry::new(self.items.entry(value)),
602            &mut self.count,
603            PhantomData,
604        ))
605    }
606
607    /// Adds a value to the bag.
608    ///
609    /// The number of occurrences of the value previously in the bag is returned.
610    ///
611    /// # Examples
612    ///
613    /// ```
614    /// use hashbag::HashBag;
615    ///
616    /// let mut bag = HashBag::new();
617    ///
618    /// assert_eq!(bag.insert(2), 0);
619    /// assert_eq!(bag.insert(2), 1);
620    /// assert_eq!(bag.insert(2), 2);
621    /// assert_eq!(bag.set_len(), 1);
622    /// assert_eq!(bag.len(), 3);
623    /// ```
624    #[inline]
625    pub fn insert(&mut self, value: T) -> usize {
626        self.insert_many(value, 1)
627    }
628
629    /// Adds multiple occurrences of a value to the bag.
630    ///
631    /// The number of occurrences of the value previously in the bag is returned.
632    ///
633    /// # Examples
634    ///
635    /// ```
636    /// use hashbag::HashBag;
637    ///
638    /// let mut bag = HashBag::new();
639    ///
640    /// assert_eq!(bag.insert_many(2, 1), 0);
641    /// assert_eq!(bag.insert_many(2, 2), 1);
642    /// assert_eq!(bag.insert_many(2, 4), 3);
643    /// assert_eq!(bag.set_len(), 1);
644    /// assert_eq!(bag.len(), 7);
645    /// ```
646    #[inline]
647    pub fn insert_many(&mut self, value: T, count: usize) -> usize {
648        if count == 0 {
649            return self.contains(&value);
650        }
651        self.count += count;
652        let n = self.items.entry(value).or_insert(0);
653        let was_there = *n;
654        *n += count;
655        was_there
656    }
657
658    /// Adds a value to the bag, replacing all existing occurrences, if any, that equal the given
659    /// one.
660    ///
661    /// The number of occurrences of the value previously in the bag is returned.
662    ///
663    /// # Examples
664    ///
665    /// ```
666    /// use hashbag::HashBag;
667    ///
668    /// let mut bag = HashBag::new();
669    /// bag.insert(Vec::<i32>::new());
670    /// bag.insert(Vec::<i32>::new());
671    /// assert_eq!(bag.contains(&[][..]), 2);
672    /// assert_eq!(bag.get(&[][..]).unwrap().0.capacity(), 0);
673    ///
674    /// bag.replace(Vec::with_capacity(10));
675    /// assert_eq!(bag.contains(&[][..]), 1);
676    /// assert_eq!(bag.get(&[][..]).unwrap().0.capacity(), 10);
677    /// ```
678    #[inline]
679    pub fn replace(&mut self, value: T) -> usize {
680        let n = self.items.remove(&value).unwrap_or(0);
681        self.count -= n;
682        self.items.insert(value, 1);
683        self.count += 1;
684        n
685    }
686
687    /// Removes a value from the bag.
688    ///
689    /// The number of occurrences of the value previously in the bag is returned.
690    ///
691    /// The value may be any borrowed form of the bag's value type, but
692    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
693    /// the value type.
694    ///
695    /// # Examples
696    ///
697    /// ```
698    /// use hashbag::HashBag;
699    ///
700    /// let mut bag = HashBag::new();
701    ///
702    /// bag.insert_many('x', 2);
703    /// assert_eq!(bag.contains(&'x'), 2);
704    /// assert_eq!(bag.remove(&'x'), 2);
705    /// assert_eq!(bag.contains(&'x'), 1);
706    /// assert_eq!(bag.remove(&'x'), 1);
707    /// assert_eq!(bag.contains(&'x'), 0);
708    /// assert_eq!(bag.remove(&'x'), 0);
709    /// ```
710    #[inline]
711    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> usize
712    where
713        T: Borrow<Q>,
714        Q: Hash + Eq,
715    {
716        match self.items.get_mut(value) {
717            None => 0,
718            #[cfg(debug_assertions)]
719            Some(n) if *n == 0 => unreachable!(),
720            Some(n) if *n == 1 => {
721                self.count -= 1;
722                self.items.remove(value);
723                1
724            }
725            Some(n) => {
726                self.count -= 1;
727                *n -= 1;
728                *n + 1
729            }
730        }
731    }
732
733    /// Removes multiple of a value from the bag. If `quantity` is greater than the number of
734    /// occurences, zero occurances will remain.
735    ///
736    /// The number of occurrences of the value currently in the bag is returned.
737    ///
738    /// The value may be any borrowed form of the bag's value type, but
739    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
740    /// the value type.
741    ///
742    /// # Examples
743    ///
744    /// ```
745    /// use hashbag::HashBag;
746    ///
747    /// let mut bag = HashBag::new();
748    ///
749    /// bag.insert_many('x', 10);
750    /// assert_eq!(bag.contains(&'x'), 10);
751    /// assert_eq!(bag.remove_up_to(&'x', 3), 7);
752    /// assert_eq!(bag.contains(&'x'), 7);
753    /// assert_eq!(bag.remove_up_to(&'x', 10), 0);
754    /// ```
755    #[inline]
756    pub fn remove_up_to<Q: ?Sized>(&mut self, value: &Q, quantity: usize) -> usize
757    where
758        T: Borrow<Q>,
759        Q: Hash + Eq,
760    {
761        match self.items.get_mut(value) {
762            None => 0,
763            Some(&mut n) if n <= quantity => {
764                self.count -= n;
765                self.items.remove(value);
766                0
767            }
768            Some(n) => {
769                self.count -= quantity;
770                *n -= quantity;
771                *n
772            }
773        }
774    }
775
776    /// Returns an iterator over all of the elements that are in `self` or `other`.
777    /// The iterator also yields the respective counts in `self` and `other` in that order.
778    /// Elements that are in `self` are yielded before any elements that are exclusively in `other`.
779    /// Each distinct element is yielded only once.
780    ///
781    /// # Examples
782    /// ```
783    /// use hashbag::HashBag;
784    /// use std::collections::HashSet;
785    /// use std::iter::FromIterator;
786    ///
787    /// let a: HashBag<_> = "hash".chars().collect();
788    /// let b: HashBag<_> = "math".chars().collect();
789    /// let expected: HashSet<_> = HashSet::from_iter([(&'h', 2, 1), (&'a', 1, 1), (&'s', 1, 0), (&'m', 0, 1), (&'t', 0, 1)]);
790    /// let actual: HashSet<_> = a.outer_join(&b).collect();
791    /// assert_eq!(expected, actual);
792    /// ```
793    pub fn outer_join<'a, OtherS>(
794        &'a self,
795        other: &'a HashBag<T, OtherS>,
796    ) -> impl Iterator<Item = (&'a T, usize, usize)>
797    where
798        OtherS: BuildHasher,
799    {
800        self.items
801            .iter()
802            .map(move |(x, &self_count)| (x, self_count, other.contains(x)))
803            .chain(other.items.iter().filter_map(move |(x, &other_count)| {
804                let self_count = self.contains(x);
805                if self_count == 0 {
806                    Some((x, self_count, other_count))
807                } else {
808                    None
809                }
810            }))
811    }
812
813    /// Returns an iterator over all the elements that are in `self` with a
814    /// higher occurrence count than in `other`. The count in the returned
815    /// iterator represents how many more of a given element are in `self` than
816    /// `other`.
817    ///
818    /// # Examples
819    ///
820    /// ```
821    /// use hashbag::HashBag;
822    /// use std::collections::HashSet;
823    /// use std::iter::FromIterator;
824    ///
825    /// let a: HashBag<_> = [1, 2, 3, 3].iter().cloned().collect();
826    /// let b: HashBag<_> = [2, 3].iter().cloned().collect();
827    /// let expected: HashSet<_> = HashSet::from_iter([(&1, 1), (&3, 1)]);
828    /// let actual: HashSet<_> = a.difference(&b).collect();
829    /// assert_eq!(expected, actual);
830    /// ```
831    pub fn difference<'a, OtherS>(
832        &'a self,
833        other: &'a HashBag<T, OtherS>,
834    ) -> impl Iterator<Item = (&'a T, usize)>
835    where
836        OtherS: BuildHasher,
837    {
838        self.outer_join(other)
839            .take_while(|(_, self_count, _)| self_count > &0)
840            .filter(|(_x, self_count, other_count)| self_count > other_count)
841            .map(|(x, self_count, other_count)| (x, self_count - other_count))
842    }
843
844    /// Returns an iterator over all the elements that are in `self` or `other`.
845    /// The iterator also yields the difference in counts between `self` and `other`.
846    ///
847    /// Unlike 'difference' which only yields elements that have a higher count in `self` than in `other`,
848    /// this iterator yields all elements that are in either of the `HashBag`s. Elements that have a higher
849    /// count in `other` than in self (including elements that are not in `self`) will have a negative count.
850    ///
851    /// If the difference can be represented as an `isize`, then it will be. Otherwise, the difference will be
852    /// clamped to `isize::MIN`/`isize::MAX`, thus keeping the sign of the difference, and as much of the
853    /// magnitude as possible.
854    ///
855    /// # Examples
856    ///
857    /// ```
858    /// use hashbag::HashBag;
859    /// use std::collections::HashSet;
860    /// use std::iter::FromIterator;
861    ///
862    /// let a: HashBag<_> = [1, 2, 3, 3].iter().cloned().collect();
863    /// let b: HashBag<_> = [2, 3, 4, 4].iter().cloned().collect();
864    /// let expected: HashSet<_> = HashSet::from_iter([(&1, 1), (&2, 0), (&3, 1), (&4, -2)]);
865    /// let actual: HashSet<_> = a.signed_difference(&b).collect();
866    /// assert_eq!(expected, actual);
867    /// ```
868    pub fn signed_difference<'a, OtherS>(
869        &'a self,
870        other: &'a HashBag<T, OtherS>,
871    ) -> impl Iterator<Item = (&'a T, isize)>
872    where
873        OtherS: BuildHasher,
874    {
875        self.outer_join(other).map(|(x, self_count, other_count)| {
876            let diff = if self_count >= other_count {
877                isize::try_from(self_count - other_count).unwrap_or(std::isize::MAX)
878            } else {
879                isize::try_from(other_count - self_count)
880                    .map(|x| -x)
881                    .unwrap_or(std::isize::MIN)
882            };
883            (x, diff)
884        })
885    }
886
887    /// Returns an iterator over all of the elements that are in `self` but not in `other`.
888    ///
889    /// # Examples
890    /// ```
891    /// use hashbag::HashBag;
892    /// use std::collections::HashSet;
893    /// use std::iter::FromIterator;
894    ///
895    /// let a: HashBag<_> = [1, 2, 3, 3].iter().cloned().collect();
896    /// let b: HashBag<_> = [2, 3].iter().cloned().collect();
897    /// let expected: HashSet<_> = HashSet::from_iter([(&1, 1)]);
898    /// let actual: HashSet<_> = a.not_in(&b).collect();
899    /// assert_eq!(expected, actual);
900    /// ```
901    pub fn not_in<'a, OtherS>(
902        &'a self,
903        other: &'a HashBag<T, OtherS>,
904    ) -> impl Iterator<Item = (&'a T, usize)>
905    where
906        OtherS: BuildHasher,
907    {
908        self.outer_join(other)
909            .take_while(|(_, self_count, _)| self_count > &0)
910            .filter_map(|(k, self_count, other_count)| {
911                if other_count == 0 {
912                    Some((k, self_count))
913                } else {
914                    None
915                }
916            })
917    }
918
919    /// Removes a value that is equal to the given one, and returns it if it was the last.
920    ///
921    /// If the matching value is not the last, a reference to the remainder is given, along with
922    /// the number of occurrences prior to the removal.
923    ///
924    /// The value may be any borrowed form of the bag's value type, but
925    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
926    /// the value type.
927    ///
928    /// # Examples
929    ///
930    /// ```
931    /// use hashbag::HashBag;
932    ///
933    /// let mut bag: HashBag<_> = [1, 2, 3, 3].iter().cloned().collect();
934    /// assert_eq!(bag.try_take(&2), Ok(2));
935    /// assert_eq!(bag.try_take(&3), Err(Some((&3, 2))));
936    /// assert_eq!(bag.try_take(&3), Ok(3));
937    /// assert_eq!(bag.try_take(&4), Err(None));
938    /// ```
939    #[inline]
940    pub fn try_take<Q: ?Sized>(&mut self, value: &Q) -> Result<T, Option<(&T, usize)>>
941    where
942        T: Borrow<Q>,
943        Q: Hash + Eq,
944    {
945        // TODO: it should be possible to make this more efficient
946        match self.items.remove_entry(value) {
947            Some((t, 1)) => {
948                self.count -= 1;
949                Ok(t)
950            }
951            Some((t, n)) => {
952                self.count -= 1;
953                self.items.insert(t, n - 1);
954                Err(Some(
955                    self.items
956                        .get_key_value(value)
957                        .map(|(t, n)| (t, *n + 1))
958                        .unwrap(),
959                ))
960            }
961            None => Err(None),
962        }
963    }
964
965    /// Removes and returns all occurrences of the value, if any, that is equal to the given one.
966    ///
967    /// The value may be any borrowed form of the bag's value type, but
968    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
969    /// the value type.
970    ///
971    /// # Examples
972    ///
973    /// ```
974    /// use hashbag::HashBag;
975    ///
976    /// let mut bag: HashBag<_> = [1, 2, 3, 3].iter().cloned().collect();
977    /// assert_eq!(bag.take_all(&2), Some((2, 1)));
978    /// assert_eq!(bag.take_all(&3), Some((3, 2)));
979    /// assert_eq!(bag.take_all(&2), None);
980    /// assert_eq!(bag.take_all(&3), None);
981    /// ```
982    #[inline]
983    pub fn take_all<Q: ?Sized>(&mut self, value: &Q) -> Option<(T, usize)>
984    where
985        T: Borrow<Q>,
986        Q: Hash + Eq,
987    {
988        let (t, n) = self.items.remove_entry(value)?;
989        self.count -= n;
990        Some((t, n))
991    }
992
993    /// Retains only the values specified by the predicate.
994    ///
995    /// In other words, for each value `v` retain only `f(&v)` occurrences.
996    ///
997    /// # Examples
998    ///
999    /// ```
1000    /// use hashbag::HashBag;
1001    ///
1002    /// let xs = [0,0,0,0,0,1,1,1,1,2,2,2,3,3,4];
1003    /// let mut bag: HashBag<i32> = xs.iter().cloned().collect();
1004    /// bag.retain(|&k, _| k as usize);
1005    /// assert_eq!(bag.set_len(), 4); // >= 1 of all but value 0
1006    /// assert_eq!(bag.len(), 6);
1007    /// assert_eq!(bag.contains(&0), 0);
1008    /// assert_eq!(bag.contains(&1), 1);
1009    /// assert_eq!(bag.contains(&2), 2);
1010    /// assert_eq!(bag.contains(&3), 2);
1011    /// assert_eq!(bag.contains(&4), 1);
1012    /// ```
1013    pub fn retain<F>(&mut self, mut f: F)
1014    where
1015        F: FnMut(&T, usize) -> usize,
1016    {
1017        let count = &mut self.count;
1018        self.items.retain(|t, n| {
1019            let keep = std::cmp::min(*n, f(t, *n));
1020            *count -= *n - keep;
1021            if keep == 0 {
1022                false
1023            } else {
1024                *n = keep;
1025                true
1026            }
1027        });
1028    }
1029}
1030
1031// ======== standard traits
1032
1033use std::fmt;
1034use std::marker::PhantomData;
1035
1036impl<T> fmt::Debug for HashBag<T>
1037where
1038    T: fmt::Debug,
1039{
1040    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1041        fmt.debug_set().entries(self.iter()).finish()
1042    }
1043}
1044
1045impl<T, S> Default for HashBag<T, S>
1046where
1047    T: Eq + Hash,
1048    S: BuildHasher + Default,
1049{
1050    fn default() -> Self {
1051        Self::with_hasher(S::default())
1052    }
1053}
1054
1055impl<T, S> PartialEq<HashBag<T, S>> for HashBag<T, S>
1056where
1057    T: Eq + Hash,
1058    S: BuildHasher,
1059{
1060    fn eq(&self, other: &Self) -> bool {
1061        self.count == other.count && self.items == other.items
1062    }
1063}
1064
1065impl<T, S> Eq for HashBag<T, S>
1066where
1067    T: Eq + Hash,
1068    S: BuildHasher,
1069{
1070}
1071
1072impl<'a, T, S> Extend<&'a T> for HashBag<T, S>
1073where
1074    T: 'a + Eq + Hash + Clone,
1075    S: BuildHasher,
1076{
1077    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
1078        for e in iter {
1079            self.insert(e.clone());
1080        }
1081    }
1082}
1083
1084impl<'a, T, S> Extend<(&'a T, usize)> for HashBag<T, S>
1085where
1086    T: 'a + Eq + Hash + Clone,
1087    S: BuildHasher,
1088{
1089    fn extend<I: IntoIterator<Item = (&'a T, usize)>>(&mut self, iter: I) {
1090        for (e, n) in iter {
1091            self.count += n;
1092            *self.items.entry(e.clone()).or_insert(0) += n;
1093        }
1094    }
1095}
1096
1097impl<T, S> Extend<T> for HashBag<T, S>
1098where
1099    T: Eq + Hash,
1100    S: BuildHasher,
1101{
1102    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1103        for e in iter {
1104            self.insert(e);
1105        }
1106    }
1107}
1108
1109impl<T, S> Extend<(T, usize)> for HashBag<T, S>
1110where
1111    T: Eq + Hash,
1112    S: BuildHasher,
1113{
1114    fn extend<I: IntoIterator<Item = (T, usize)>>(&mut self, iter: I) {
1115        for (e, n) in iter {
1116            self.count += n;
1117            if n != 0 {
1118                *self.items.entry(e).or_insert(0) += n;
1119            }
1120        }
1121    }
1122}
1123
1124impl<T, S> std::iter::FromIterator<T> for HashBag<T, S>
1125where
1126    T: Eq + Hash,
1127    S: BuildHasher + Default,
1128{
1129    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1130        let mut bag = Self::default();
1131        bag.extend(iter);
1132        bag
1133    }
1134}
1135
1136impl<T, S> std::iter::FromIterator<(T, usize)> for HashBag<T, S>
1137where
1138    T: Eq + Hash,
1139    S: BuildHasher + Default,
1140{
1141    fn from_iter<I: IntoIterator<Item = (T, usize)>>(iter: I) -> Self {
1142        let mut bag = Self::default();
1143        bag.extend(iter);
1144        bag
1145    }
1146}
1147
1148impl<'a, T, S> IntoIterator for &'a HashBag<T, S> {
1149    type Item = &'a T;
1150    type IntoIter = Iter<'a, T>;
1151    fn into_iter(self) -> Iter<'a, T> {
1152        self.iter()
1153    }
1154}
1155
1156impl<T, S> IntoIterator for HashBag<T, S> {
1157    type Item = (T, usize);
1158    type IntoIter = IntoIter<T>;
1159    fn into_iter(self) -> IntoIter<T> {
1160        IntoIter(self.items.into_iter())
1161    }
1162}
1163
1164// ======== entry type
1165#[cfg(feature = "amortize")]
1166pub(crate) mod entry {
1167    use griddle::hash_map::Entry;
1168
1169    #[derive(Debug)]
1170    pub(crate) struct ForiegnEntry<'a, T, S> {
1171        pub(crate) entry: Entry<'a, T, usize, S>,
1172    }
1173
1174    impl<'a, T, S> ForiegnEntry<'a, T, S> {
1175        pub(crate) fn new(entry: Entry<'a, T, usize, S>) -> Self {
1176            Self { entry }
1177        }
1178
1179        pub(crate) fn get_mut(&mut self) -> Option<&mut usize> {
1180            match &mut self.entry {
1181                Entry::Occupied(entry) => Some(entry.get_mut()),
1182                Entry::Vacant(_) => None,
1183            }
1184        }
1185    }
1186}
1187#[cfg(not(feature = "amortize"))]
1188pub(crate) mod entry {
1189    use std::{collections::hash_map::Entry, marker::PhantomData};
1190
1191    #[derive(Debug)]
1192    pub(crate) struct ForiegnEntry<'a, T, S> {
1193        pub(crate) entry: Entry<'a, T, usize>,
1194        data: PhantomData<S>,
1195    }
1196
1197    impl<'a, T, S> ForiegnEntry<'a, T, S> {
1198        pub(crate) fn new(entry: Entry<'a, T, usize>) -> Self {
1199            Self {
1200                entry,
1201                data: PhantomData,
1202            }
1203        }
1204
1205        pub(crate) fn get_mut(&mut self) -> Option<&mut usize> {
1206            match &mut self.entry {
1207                Entry::Occupied(entry) => Some(entry.get_mut()),
1208                Entry::Vacant(_) => None,
1209            }
1210        }
1211    }
1212}
1213
1214use entry::ForiegnEntry;
1215
1216type EntryInner<'a, T, S> = (ForiegnEntry<'a, T, S>, &'a mut usize, PhantomData<S>);
1217
1218#[derive(Debug)]
1219/// A view into a single entry in the bag, which may either be vacant or occupied.
1220/// This `enum` is constructed from the [`entry`](HashBag::entry) method on [`HashBag`]
1221pub struct Entry<'a, T, S>(EntryInner<'a, T, S>);
1222
1223impl<'a, T, S> Entry<'a, T, S>
1224where
1225    T: Hash + Eq,
1226    S: BuildHasher,
1227{
1228    /// Provides in-place mutable access to an occupied entry before potential inserts into the
1229    /// map.
1230    pub fn and_modify<F>(mut self, f: F) -> Self
1231    where
1232        F: FnOnce(&mut usize),
1233    {
1234        if let Some(n) = self.0 .0.get_mut() {
1235            let init = *n;
1236            f(n);
1237            *self.0 .1 += *n;
1238            *self.0 .1 -= init;
1239        }
1240        Self((self.0 .0, self.0 .1, PhantomData))
1241    }
1242
1243    /// Returns a reference to the entry's value.
1244    pub fn value(&self) -> &T {
1245        self.0 .0.entry.key()
1246    }
1247
1248    /// Ensures there is at least one instance of the value before returning a mutable reference
1249    /// to the value's count
1250    pub fn or_insert(mut self) -> usize {
1251        if self.0 .0.get_mut().is_none() {
1252            *self.0 .1 += 1;
1253        }
1254        *self.0 .0.entry.or_insert(1)
1255    }
1256
1257    /// Ensures there is at least `quantity` instances of the value before returning a mutable reference
1258    /// to the value's count
1259    pub fn or_insert_many(mut self, quantity: usize) -> usize {
1260        if self.0 .0.get_mut().is_none() {
1261            *self.0 .1 += quantity;
1262        }
1263        *self.0 .0.entry.or_insert(quantity)
1264    }
1265}
1266
1267// ======== iterators
1268
1269#[cfg(feature = "amortize")]
1270type IterInner<'a, T> = griddle::hash_map::Iter<'a, T, usize>;
1271#[cfg(not(feature = "amortize"))]
1272type IterInner<'a, T> = std::collections::hash_map::Iter<'a, T, usize>;
1273
1274/// An iterator over the items of a `HashBag`.
1275///
1276/// Each value is repeated as many times as it occurs in the bag.
1277///
1278/// This `struct` is created by [`HashBag::iter`].
1279/// See its documentation for more.
1280pub struct Iter<'a, T> {
1281    iter: IterInner<'a, T>,
1282    repeat: Option<(&'a T, usize)>,
1283    left: usize,
1284}
1285
1286impl<'a, T> std::iter::FusedIterator for Iter<'a, T> where IterInner<'a, T>: std::iter::FusedIterator
1287{}
1288
1289impl<'a, T> ExactSizeIterator for Iter<'a, T> where IterInner<'a, T>: ExactSizeIterator {}
1290
1291impl<'a, T> Clone for Iter<'a, T> {
1292    fn clone(&self) -> Self {
1293        Iter {
1294            iter: self.iter.clone(),
1295            repeat: self.repeat,
1296            left: self.left,
1297        }
1298    }
1299}
1300
1301impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
1302    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1303        fmt.debug_set().entries(self.clone()).finish()
1304    }
1305}
1306
1307impl<'a, T> Iter<'a, T> {
1308    fn new(it: IterInner<'a, T>, n: usize) -> Self {
1309        Self {
1310            iter: it,
1311            repeat: None,
1312            left: n,
1313        }
1314    }
1315}
1316
1317impl<'a, T> Iterator for Iter<'a, T> {
1318    type Item = &'a T;
1319    fn next(&mut self) -> Option<Self::Item> {
1320        if let Some((t, ref mut n)) = self.repeat {
1321            if *n == 0 {
1322                self.repeat = None;
1323            } else {
1324                *n -= 1;
1325                self.left -= 1;
1326                return Some(t);
1327            }
1328        }
1329
1330        let (next, n) = self.iter.next()?;
1331        if *n > 1 {
1332            self.repeat = Some((next, *n - 1));
1333        }
1334        self.left -= 1;
1335        Some(next)
1336    }
1337
1338    fn size_hint(&self) -> (usize, Option<usize>) {
1339        (self.left, Some(self.left))
1340    }
1341}
1342
1343/// An iterator over the distinct items of a `HashBag` and their occurrence counts.
1344///
1345/// This `struct` is created by [`HashBag::set_iter`].
1346/// See its documentation for more.
1347pub struct SetIter<'a, T>(IterInner<'a, T>);
1348
1349impl<'a, T> std::iter::FusedIterator for SetIter<'a, T> where
1350    IterInner<'a, T>: std::iter::FusedIterator
1351{
1352}
1353
1354impl<'a, T> ExactSizeIterator for SetIter<'a, T> where IterInner<'a, T>: ExactSizeIterator {}
1355
1356impl<'a, T> Clone for SetIter<'a, T> {
1357    fn clone(&self) -> Self {
1358        SetIter(self.0.clone())
1359    }
1360}
1361
1362impl<T: fmt::Debug> fmt::Debug for SetIter<'_, T> {
1363    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1364        fmt.debug_set().entries(self.clone()).finish()
1365    }
1366}
1367
1368impl<'a, T> Iterator for SetIter<'a, T> {
1369    type Item = (&'a T, usize);
1370    fn next(&mut self) -> Option<Self::Item> {
1371        self.0.next().map(|(t, n)| (t, *n))
1372    }
1373
1374    fn size_hint(&self) -> (usize, Option<usize>) {
1375        self.0.size_hint()
1376    }
1377}
1378
1379#[cfg(feature = "amortize")]
1380type IntoIterInner<T> = griddle::hash_map::IntoIter<T, usize>;
1381#[cfg(not(feature = "amortize"))]
1382type IntoIterInner<T> = std::collections::hash_map::IntoIter<T, usize>;
1383
1384/// An owning iterator over the distinct items of a `HashBag` and their occurrence counts.
1385///
1386/// This `struct` is created by using the implementation of [`IntoIterator`] for [`HashBag`].
1387pub struct IntoIter<T>(IntoIterInner<T>);
1388
1389impl<T> std::iter::FusedIterator for IntoIter<T> where IntoIterInner<T>: std::iter::FusedIterator {}
1390
1391impl<T> ExactSizeIterator for IntoIter<T> where IntoIterInner<T>: ExactSizeIterator {}
1392
1393impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
1394    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1395        self.0.fmt(fmt)
1396    }
1397}
1398
1399impl<T> Iterator for IntoIter<T> {
1400    type Item = (T, usize);
1401    fn next(&mut self) -> Option<Self::Item> {
1402        self.0.next()
1403    }
1404
1405    fn size_hint(&self) -> (usize, Option<usize>) {
1406        self.0.size_hint()
1407    }
1408}
1409
1410#[cfg(feature = "amortize")]
1411type DrainInner<'a, T> = griddle::hash_map::Drain<'a, T, usize>;
1412#[cfg(not(feature = "amortize"))]
1413type DrainInner<'a, T> = std::collections::hash_map::Drain<'a, T, usize>;
1414
1415/// An draining iterator over the distinct items of a `HashBag` and their occurrence counts.
1416///
1417/// This `struct` is created by [`HashBag::drain`].
1418/// See its documentation for more.
1419pub struct Drain<'a, T>(DrainInner<'a, T>);
1420
1421impl<'a, T> std::iter::FusedIterator for Drain<'a, T> where
1422    DrainInner<'a, T>: std::iter::FusedIterator
1423{
1424}
1425
1426impl<'a, T> ExactSizeIterator for Drain<'a, T> where DrainInner<'a, T>: ExactSizeIterator {}
1427
1428impl<'a, T: fmt::Debug> fmt::Debug for Drain<'a, T> {
1429    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1430        self.0.fmt(fmt)
1431    }
1432}
1433
1434impl<'a, T> Iterator for Drain<'a, T> {
1435    type Item = (T, usize);
1436    fn next(&mut self) -> Option<Self::Item> {
1437        self.0.next()
1438    }
1439
1440    fn size_hint(&self) -> (usize, Option<usize>) {
1441        self.0.size_hint()
1442    }
1443}
1444
1445#[cfg(test)]
1446mod tests {
1447    use std::collections::HashSet;
1448    use std::iter::FromIterator;
1449
1450    use super::*;
1451
1452    #[test]
1453    fn format_all_the_things() {
1454        let mut vikings: HashBag<&'static str> =
1455            ["Einar", "Olaf", "Harald"].iter().cloned().collect();
1456        println!("{:?}", vikings);
1457        println!("{:?}", vikings.iter());
1458        println!("{:?}", vikings.set_iter());
1459        println!("{:?}", vikings.clone().into_iter());
1460        println!("{:?}", vikings.drain());
1461    }
1462
1463    #[test]
1464    fn sane_iterators() {
1465        let mut vikings: HashBag<&'static str> =
1466            ["Einar", "Einar", "Harald"].iter().cloned().collect();
1467        assert_eq!(vikings.iter().count(), 3);
1468        assert_eq!(vikings.iter().size_hint(), (3, Some(3)));
1469        assert_eq!(vikings.iter().clone().count(), 3);
1470        assert_eq!(vikings.set_iter().count(), 2);
1471        assert_eq!(vikings.set_iter().clone().count(), 2);
1472        assert_eq!(vikings.set_iter().size_hint(), (2, Some(2)));
1473        let ii = vikings.clone().into_iter();
1474        assert_eq!(ii.size_hint(), (2, Some(2)));
1475        assert_eq!(ii.count(), 2);
1476        let di = vikings.drain();
1477        assert_eq!(di.size_hint(), (2, Some(2)));
1478        assert_eq!(di.count(), 2);
1479    }
1480
1481    #[test]
1482    fn test_difference_size_hint() {
1483        let bag: HashBag<_> = [3, 2, 1].iter().cloned().collect();
1484        let empty_bag = HashBag::new();
1485        let mut difference = bag.difference(&empty_bag);
1486
1487        // Since the difference has the same number of entries as the bag, we
1488        // can predict how the size_hint() will behave, because the iteration
1489        // order does not matter
1490        assert_eq!(difference.size_hint(), (0, Some(3)));
1491        difference.next().unwrap();
1492        assert_eq!(difference.size_hint(), (0, Some(2)));
1493        difference.next().unwrap();
1494        assert_eq!(difference.size_hint(), (0, Some(1)));
1495        difference.next().unwrap();
1496        assert_eq!(difference.size_hint(), (0, Some(0)));
1497        assert_eq!(difference.next(), None);
1498        assert_eq!(difference.size_hint(), (0, Some(0)));
1499    }
1500
1501    #[test]
1502    fn test_difference_from_empty() {
1503        do_test_difference(&[], &[], &[]);
1504        do_test_difference(&[], &[1], &[]);
1505        do_test_difference(&[], &[1, 1], &[]);
1506        do_test_difference(&[], &[1, 1, 2], &[]);
1507    }
1508
1509    #[test]
1510    fn test_difference_from_one() {
1511        do_test_difference(&[1], &[], &[1]);
1512        do_test_difference(&[1], &[1], &[]);
1513        do_test_difference(&[1], &[1, 1], &[]);
1514        do_test_difference(&[1], &[2], &[1]);
1515        do_test_difference(&[1], &[1, 2], &[]);
1516        do_test_difference(&[1], &[2, 2], &[1]);
1517    }
1518
1519    #[test]
1520    fn test_difference_from_duplicate_ones() {
1521        do_test_difference(&[1, 1], &[], &[1, 1]);
1522        do_test_difference(&[1, 1], &[1], &[1]);
1523        do_test_difference(&[1, 1], &[1, 1], &[]);
1524        do_test_difference(&[1, 1], &[2], &[1, 1]);
1525        do_test_difference(&[1, 1], &[1, 2], &[1]);
1526        do_test_difference(&[1, 1], &[2, 2], &[1, 1]);
1527    }
1528
1529    #[test]
1530    fn test_difference_from_one_one_two() {
1531        do_test_difference(&[1, 1, 2], &[], &[1, 1, 2]);
1532        do_test_difference(&[1, 1, 2], &[1], &[1, 2]);
1533        do_test_difference(&[1, 1, 2], &[1, 1], &[2]);
1534        do_test_difference(&[1, 1, 2], &[2], &[1, 1]);
1535        do_test_difference(&[1, 1, 2], &[1, 2], &[1]);
1536        do_test_difference(&[1, 1, 2], &[2, 2], &[1, 1]);
1537    }
1538
1539    #[test]
1540    fn test_difference_from_larger_bags() {
1541        do_test_difference(&[1, 2, 2, 3], &[3], &[1, 2, 2]);
1542        do_test_difference(&[1, 2, 2, 3], &[4], &[1, 2, 2, 3]);
1543        do_test_difference(&[2, 2, 2, 2], &[2, 2], &[2, 2]);
1544        do_test_difference(&[2, 2, 2, 2], &[], &[2, 2, 2, 2]);
1545    }
1546
1547    fn do_test_difference(
1548        self_entries: &[isize],
1549        other_entries: &[isize],
1550        expected_entries: &[isize],
1551    ) {
1552        let this = self_entries.iter().collect::<HashBag<_>>();
1553        let other = other_entries.iter().collect::<HashBag<_>>();
1554        let expected = expected_entries.iter().collect::<HashBag<_>>();
1555        let mut actual = HashBag::new();
1556        for (t, n) in this.difference(&other) {
1557            actual.insert_many(*t, n);
1558        }
1559
1560        assert_eq!(actual, expected);
1561    }
1562
1563    #[test]
1564    fn test_outer_join_order_with_disjoint_sets() {
1565        do_test_outer_join_order(&[1, 2, 3], &[4, 5, 6]);
1566        do_test_outer_join_order(&[1, 2, 2, 3], &[4, 4, 5, 6]);
1567    }
1568
1569    #[test]
1570    fn test_outer_join_order_with_overlap() {
1571        do_test_outer_join_order(&[1, 2, 3], &[2, 3, 4]);
1572        do_test_outer_join_order(&[1, 1, 2, 3], &[2, 3, 3, 3, 4]);
1573    }
1574
1575    fn do_test_outer_join_order(this: &[usize], other: &[usize]) {
1576        let this_hashbag: HashBag<usize> = this.iter().cloned().collect();
1577        let other_hashbag: HashBag<usize> = other.iter().cloned().collect();
1578
1579        // Assert that the first yielded key that's exclusive to other (i.e. self_count is 0)
1580        // comes AFTER all of the keys in self
1581        let min_other_exclusive_key_idx = this_hashbag
1582            .outer_join(&other_hashbag)
1583            .enumerate()
1584            .find(|(_, (_, self_count, _))| self_count == &0)
1585            .map(|(idx, _)| idx);
1586        // If no such element exists that means all of the keys in other
1587        // are in self so there's no thing to assert.
1588        if let Some(idx) = min_other_exclusive_key_idx {
1589            assert_eq!(idx, this_hashbag.set_len());
1590        }
1591    }
1592
1593    #[test]
1594    fn test_outer_join_with_empty_self() {
1595        do_test_outer_join(&[], &[1, 2, 2, 3], &[(&1, 0, 1), (&2, 0, 2), (&3, 0, 1)]);
1596    }
1597
1598    #[test]
1599    fn test_outer_join_with_empty_other() {
1600        do_test_outer_join(&[1, 2, 2, 3], &[], &[(&1, 1, 0), (&2, 2, 0), (&3, 1, 0)]);
1601    }
1602
1603    #[test]
1604    fn test_outer_join_with_overlap() {
1605        do_test_outer_join(
1606            &[1, 2, 2, 3, 3],
1607            &[3, 4, 5, 5],
1608            &[(&1, 1, 0), (&2, 2, 0), (&3, 2, 1), (&4, 0, 1), (&5, 0, 2)],
1609        );
1610    }
1611
1612    fn do_test_outer_join(
1613        this: &[usize],
1614        other: &[usize],
1615        expected_entries: &[(&usize, usize, usize)],
1616    ) {
1617        let this_hashbag: HashBag<_> = this.iter().cloned().collect();
1618        let other_hashbag: HashBag<_> = other.iter().cloned().collect();
1619        let expected: HashSet<_> = HashSet::from_iter(expected_entries.iter().cloned());
1620        let actual: HashSet<_> = this_hashbag.outer_join(&other_hashbag).collect();
1621        assert_eq!(expected, actual);
1622    }
1623
1624    #[test]
1625    fn test_not_in_with_empty_self() {
1626        do_test_not_in(&[], &[1, 2, 3, 3], &[]);
1627    }
1628
1629    #[test]
1630    fn test_not_in_with_empty_other() {
1631        do_test_not_in(&[1, 2, 3, 3], &[], &[1, 2, 3, 3]);
1632    }
1633
1634    #[test]
1635    fn test_not_in_with_overlap() {
1636        do_test_not_in(&[1, 2, 3, 3], &[2, 4], &[1, 3, 3]);
1637    }
1638
1639    fn do_test_not_in(this: &[usize], other: &[usize], expected_entries: &[usize]) {
1640        let this_hashbag: HashBag<_> = this.iter().cloned().collect();
1641        let other_hashbag: HashBag<_> = other.iter().cloned().collect();
1642        let expected: HashBag<_> = expected_entries.iter().cloned().collect();
1643        let actual: HashBag<_> =
1644            this_hashbag
1645                .not_in(&other_hashbag)
1646                .fold(HashBag::new(), |mut bag, (k, count)| {
1647                    bag.insert_many(*k, count);
1648                    bag
1649                });
1650        assert_eq!(expected, actual);
1651    }
1652
1653    #[test]
1654    fn test_signed_difference_with_empty_self() {
1655        do_test_signed_difference(&[], &[1, 2, 2, 3], &[(&1, -1), (&2, -2), (&3, -1)]);
1656    }
1657
1658    #[test]
1659    fn test_signed_difference_with_empty_other() {
1660        do_test_signed_difference(&[1, 2, 2, 3], &[], &[(&1, 1), (&2, 2), (&3, 1)]);
1661    }
1662
1663    #[test]
1664    fn test_signed_difference_with_overlap() {
1665        do_test_signed_difference(
1666            &[1, 2, 2, 3, 3],
1667            &[3, 4, 5, 5],
1668            &[(&1, 1), (&2, 2), (&3, 1), (&4, -1), (&5, -2)],
1669        );
1670    }
1671
1672    #[test]
1673    fn test_signed_difference_with_both_large() {
1674        let mut this_hashbag = HashBag::new();
1675        let mut other_hashbag = HashBag::new();
1676
1677        let large_count = std::isize::MAX as usize;
1678        this_hashbag.insert_many(1, large_count + 1000);
1679        other_hashbag.insert_many(1, large_count);
1680
1681        let expected: HashSet<_> = HashSet::from_iter([(&1, 1000)].iter().cloned());
1682        let actual: HashSet<_> = this_hashbag.signed_difference(&other_hashbag).collect();
1683        assert_eq!(expected, actual);
1684
1685        // and in reverse:
1686        let expected: HashSet<_> = HashSet::from_iter([(&1, -1000)].iter().cloned());
1687        let actual: HashSet<_> = other_hashbag.signed_difference(&this_hashbag).collect();
1688        assert_eq!(expected, actual);
1689    }
1690
1691    #[test]
1692    fn test_signed_difference_too_large_to_hold_clamp() {
1693        let mut this_hashbag = HashBag::new();
1694        let empty_hashbag = HashBag::new();
1695
1696        let large_count = std::isize::MAX as usize;
1697        this_hashbag.insert_many(1, large_count + 1000);
1698
1699        let expected: HashSet<_> = HashSet::from_iter([(&1, std::isize::MAX)].iter().cloned());
1700        let actual: HashSet<_> = this_hashbag.signed_difference(&empty_hashbag).collect();
1701        assert_eq!(expected, actual);
1702
1703        // and in reverse:
1704        let expected: HashSet<_> = HashSet::from_iter([(&1, std::isize::MIN)].iter().cloned());
1705        let actual: HashSet<_> = empty_hashbag.signed_difference(&this_hashbag).collect();
1706        assert_eq!(expected, actual);
1707    }
1708
1709    fn do_test_signed_difference(
1710        this: &[usize],
1711        other: &[usize],
1712        expected_entries: &[(&usize, isize)],
1713    ) {
1714        let this_hashbag: HashBag<_> = this.iter().cloned().collect();
1715        let other_hashbag: HashBag<_> = other.iter().cloned().collect();
1716        let expected: HashSet<_> = HashSet::from_iter(expected_entries.iter().cloned());
1717        let actual: HashSet<_> = this_hashbag.signed_difference(&other_hashbag).collect();
1718        assert_eq!(expected, actual);
1719    }
1720
1721    #[test]
1722    fn test_no_zeros_counts() {
1723        let mut hashbag = HashBag::new();
1724        hashbag.insert(100);
1725        hashbag.retain(|_, _| 0);
1726        hashbag.insert_many(1, 0);
1727        hashbag.extend(vec![(2, 0)]);
1728        assert_eq!(hashbag.len(), 0);
1729        assert_eq!(hashbag.iter().count(), 0);
1730        assert_eq!(hashbag.set_len(), 0);
1731        assert_eq!(hashbag.set_iter().count(), 0);
1732    }
1733
1734    #[test]
1735    fn remove_up_to_affects_count() {
1736        let mut bag = HashBag::new();
1737        bag.insert_many(42, 3);
1738        assert_eq!(bag.len(), 3);
1739        assert_eq!(bag.remove_up_to(&0, 1), 0);
1740        assert_eq!(bag.len(), 3);
1741        assert_eq!(bag.remove_up_to(&42, 1), 2);
1742        assert_eq!(bag.len(), 2);
1743        assert_eq!(bag.remove_up_to(&42, 10), 0);
1744        assert_eq!(bag.len(), 0);
1745    }
1746
1747    #[test]
1748    fn entry_inserts_values() {
1749        let mut bag = HashBag::new();
1750        bag.entry(42);
1751        assert_eq!(bag.contains(&42), 0);
1752        bag.entry(84).or_insert_many(3);
1753        assert_eq!(bag.contains(&84), 3);
1754        assert_eq!(bag.len(), 3);
1755        bag.entry(84).or_insert_many(2);
1756        assert_eq!(bag.len(), 3);
1757        bag.entry(84).or_insert();
1758        assert_eq!(bag.len(), 3);
1759    }
1760
1761    #[test]
1762    fn entry_affects_count() {
1763        let mut bag = HashBag::new();
1764        bag.entry(42);
1765        assert_eq!(bag.len(), 0);
1766        bag.entry(42).and_modify(|n| *n += 3);
1767        assert_eq!(bag.len(), 0);
1768        bag.entry(42).or_insert_many(3);
1769        assert_eq!(bag.len(), 3);
1770        bag.entry(42).and_modify(|n| *n += 3);
1771        assert_eq!(bag.len(), 6);
1772        bag.entry(84).or_insert();
1773        assert_eq!(bag.len(), 7);
1774    }
1775}