1use std::hash::BuildHasher;
5
6use crate::traits::*;
7use dashmap::DashMap;
8use rayon::prelude::*;
9
10impl<V, Hasher, T> ACMapBase for DashMap<T, V, Hasher>
11where
12 T: std::hash::Hash + Eq,
13 V: Coefficient,
14 Hasher: Clone + BuildHasher + Default,
15{
16 fn with_capacity(capacity: usize) -> Self {
17 DashMap::with_capacity_and_hasher(capacity, Hasher::default())
18 }
19
20 fn len(&self) -> usize {
21 self.len()
22 }
23
24 fn clear(&mut self) {
25 Self::clear(self);
26 }
27}
28
29impl<S, V, Hasher, W> ACMapAddAssign<S, V, Hasher, W> for DashMap<W, V, Hasher>
30where
31 S: PauliStorage,
32 V: Coefficient + Sync + Send,
33 Hasher: Default + Clone + BuildHasher + Sync + Send,
34 W: PauliWordTrait + Sync + Send,
35{
36 fn add_assign(&mut self, key: W, value: V) {
37 self.entry(key)
38 .and_modify(|v| *v += value.clone())
39 .or_insert(value);
40 }
41
42 fn map_add_assign<F>(&self, dest: &mut Self, f: F)
43 where
44 F: Fn(&W, &V) -> (W, V) + Sync + Send,
45 {
46 self.par_iter().for_each(|entry| {
47 let (new_k, new_v) = f(entry.key(), entry.value());
48 dest.entry(new_k)
49 .and_modify(|v| *v += new_v.clone())
50 .or_insert(new_v);
51 });
52 }
53}
54
55impl<V, Hasher, W> ACMapMulAssign<V, Hasher> for DashMap<W, V, Hasher>
56where
57 V: Coefficient + Send + Sync,
58 Hasher: Default + Clone + BuildHasher + Sync + Send,
59 W: std::hash::Hash + std::cmp::Eq + Send + Sync,
60{
61 fn mul_assign(&mut self, value: V) {
62 self.par_iter_mut()
63 .for_each(|mut v| *v.value_mut() *= value.clone());
64 }
65}
66
67impl<'a, V, Hasher, W> ACMapIter<'a> for DashMap<W, V, Hasher>
68where
69 V: Coefficient + 'a,
70 Hasher: Default + Clone + BuildHasher + 'a,
71 W: std::hash::Hash + std::cmp::Eq + 'a,
72{
73 type Item = dashmap::mapref::multiple::RefMulti<'a, W, V>;
74 type Iter = dashmap::iter::Iter<'a, W, V, Hasher, DashMap<W, V, Hasher>>;
75
76 fn iter(&'a self) -> Self::Iter {
77 DashMap::iter(self)
78 }
79}
80
81impl<'a, P, C, Hasher, W> Trace<'a, P> for DashMap<W, C, Hasher>
82where
83 P: Sync + 'a,
84 for<'b> P: Trace<'b, W, Output = bool>,
85 C: Coefficient + Send + Sync + 'a,
86 Hasher: Clone + std::hash::BuildHasher + Default + Send + Sync + 'a,
87 W: std::hash::Hash + std::cmp::Eq + Sync + Send + 'a,
88{
89 type Output = C;
90 fn trace(&'a self, value: &'a P) -> Self::Output {
91 self.par_iter()
92 .filter(|entry| value.trace(entry.key()))
93 .map(|entry| entry.value().clone())
94 .sum()
95 }
96}
97
98impl<C, H, W> ACMapConsume for DashMap<W, C, H>
99where
100 C: Coefficient + Send + Sync,
101 H: Clone + BuildHasher + Send + Sync,
102 W: std::hash::Hash + std::cmp::Eq + Clone + Sync + Send,
103{
104 fn consume(&mut self, dest: &mut Self) {
105 dest.par_iter().for_each(|entry| {
106 self.entry(entry.key().clone())
107 .and_modify(|v| *v += entry.value().clone())
108 .or_insert_with(|| entry.value().clone());
109 });
110
111 dest.clear();
112 }
113}
114
115impl<S, C, H, W> ACMapInsert<S, C, H, W> for DashMap<W, C, H>
116where
117 S: PauliStorage,
118 C: Coefficient + Send + Sync,
119 H: Default + Clone + BuildHasher + Send + Sync,
120 W: PauliWordTrait + Send + Sync,
121{
122 fn map_insert_vec<F>(&mut self, dest: &mut Vec<(W, C)>, f: F)
123 where
124 F: Fn(&W, &mut C) -> Option<(W, C)> + Sync + Send,
125 {
126 use rayon::iter::ParallelExtend;
127 dest.par_extend(self.par_iter_mut().filter_map(|mut entry| {
128 let (k, v) = entry.pair_mut();
129 f(k, v)
130 }));
131 }
132
133 fn map_insert_multiple<F>(&mut self, dest: &mut Self, f: F)
134 where
135 F: Fn(&W, &mut C) -> Option<Vec<(W, C)>> + Sync + Send,
136 {
137 self.par_iter_mut().for_each(|mut entry| {
138 let (k, v) = entry.pair_mut();
139 if let Some(new_entries) = f(k, v) {
140 for (new_k, new_v) in new_entries {
141 dest.insert(new_k, new_v);
142 }
143 }
144 })
145 }
146}
147
148impl<S, C, H, W> ACMapContains<S, C, H, W> for DashMap<W, C, H>
149where
150 S: PauliStorage,
151 C: Coefficient + PartialEq,
152 H: BuildHasher + Clone + Default,
153 W: PauliWordTrait,
154{
155 fn contains_with<F>(&self, key: &W, f: F) -> bool
156 where
157 F: Fn(&C) -> bool,
158 {
159 self.get(key).is_some_and(|v| f(v.value()))
160 }
161}
162
163impl<S, C, H, W> ACMapScale<S, C, H, W> for DashMap<W, C, H>
164where
165 S: PauliStorage,
166 C: Coefficient + Send + Sync,
167 H: BuildHasher + Clone + Default + Sync + Send,
168 W: PauliWordTrait + Send + Sync,
169{
170 fn scale<F>(&mut self, f: F)
171 where
172 F: Fn(&W, &mut C) + Sync + Send,
173 {
174 self.par_iter_mut().for_each(|mut entry| {
175 let (k, v) = entry.pair_mut();
176 f(k, v);
177 });
178 }
179}
180
181impl<S, C, H, W> ACMapRetain<S, C, H, W> for DashMap<W, C, H>
182where
183 S: PauliStorage,
184 C: Coefficient,
185 H: BuildHasher + Clone + Default + Sync + Send,
186 W: PauliWordTrait,
187{
188 fn retain<F>(&mut self, mut f: F)
189 where
190 F: FnMut(&W, &C) -> bool,
191 {
192 Self::retain(self, |k, v| f(k, v));
193 }
194}