kaspa_utils/
hashmap.rs

1use std::collections::{hash_map::Entry, HashMap};
2use std::hash::Hash;
3
4pub trait NestedHashMapExtensions<K, K2, V> {
5    /// For use with a hashmap within a hashmap, takes an outer and inner key, and an inner value
6    /// 1) if the outer key exists with and inner hashmap the key-value pair is inserted to the existing hashmap.
7    /// 2) a new inner hashmap is created with the key-value pair if the outer key does not exist.
8    fn insert_into_nested(&mut self, outer_key: K, inner_key: K2, inner_value: V);
9}
10
11impl<K, K2, V> NestedHashMapExtensions<K, K2, V> for HashMap<K, HashMap<K2, V>>
12where
13    K: Hash + PartialEq + Eq,
14    K2: Hash + PartialEq + Eq,
15{
16    fn insert_into_nested(&mut self, outer_key: K, inner_key: K2, inner_value: V) {
17        match self.entry(outer_key) {
18            Entry::Occupied(mut entry) => {
19                entry.get_mut().insert(inner_key, inner_value);
20            }
21            Entry::Vacant(entry) => {
22                let mut inner = HashMap::with_capacity(1);
23                // We do not expect duplicate insert since we just created the hashmap.
24                let _ = &inner.insert(inner_key, inner_value);
25                entry.insert(inner);
26            }
27        }
28    }
29}
30
31pub trait GroupExtension<K, V, I>
32where
33    K: std::hash::Hash + Ord,
34    I: IntoIterator<Item = (K, V)>,
35{
36    fn group_from(v: I) -> HashMap<K, Vec<V>>;
37}
38
39impl<K, V, I> GroupExtension<K, V, I> for HashMap<K, Vec<V>>
40where
41    K: std::hash::Hash + Ord,
42    I: IntoIterator<Item = (K, V)>,
43{
44    fn group_from(v: I) -> HashMap<K, Vec<V>> {
45        let mut result = HashMap::<K, Vec<V>>::new();
46        for (a, b) in v {
47            result.entry(a).or_default().push(b);
48        }
49        result
50    }
51}