solverforge_core/domain/supply/
inverse.rs1use std::collections::HashMap;
10use std::hash::Hash;
11
12#[derive(Debug)]
37pub struct InverseSupply<V>
38where
39 V: Eq + Hash,
40{
41 inverse_map: HashMap<V, usize>,
43}
44
45impl<V> Default for InverseSupply<V>
46where
47 V: Eq + Hash,
48{
49 fn default() -> Self {
50 Self::new()
51 }
52}
53
54impl<V> InverseSupply<V>
55where
56 V: Eq + Hash,
57{
58 pub fn new() -> Self {
60 Self {
61 inverse_map: HashMap::new(),
62 }
63 }
64
65 pub fn with_capacity(capacity: usize) -> Self {
67 Self {
68 inverse_map: HashMap::with_capacity(capacity),
69 }
70 }
71
72 #[inline]
76 pub fn get(&self, value: &V) -> Option<usize> {
77 self.inverse_map.get(value).copied()
78 }
79
80 #[inline]
84 pub fn insert(&mut self, value: V, entity_idx: usize) -> Option<usize> {
85 self.inverse_map.insert(value, entity_idx)
86 }
87
88 #[inline]
92 pub fn remove(&mut self, value: &V) -> Option<usize> {
93 self.inverse_map.remove(value)
94 }
95
96 #[inline]
100 pub fn update(&mut self, old_value: Option<&V>, new_value: V, entity_idx: usize) {
101 if let Some(old) = old_value {
102 self.remove(old);
103 }
104 self.insert(new_value, entity_idx);
105 }
106
107 #[inline]
109 pub fn clear(&mut self) {
110 self.inverse_map.clear();
111 }
112
113 #[inline]
115 pub fn len(&self) -> usize {
116 self.inverse_map.len()
117 }
118
119 #[inline]
121 pub fn is_empty(&self) -> bool {
122 self.inverse_map.is_empty()
123 }
124
125 #[inline]
127 pub fn iter(&self) -> impl Iterator<Item = (&V, &usize)> {
128 self.inverse_map.iter()
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn test_insert_and_get() {
138 let mut supply: InverseSupply<i32> = InverseSupply::new();
139
140 supply.insert(1, 0);
141 supply.insert(2, 1);
142
143 assert_eq!(supply.get(&1), Some(0));
144 assert_eq!(supply.get(&2), Some(1));
145 assert_eq!(supply.get(&3), None);
146 }
147
148 #[test]
149 fn test_remove() {
150 let mut supply: InverseSupply<i32> = InverseSupply::new();
151
152 supply.insert(1, 0);
153 assert_eq!(supply.len(), 1);
154
155 let removed = supply.remove(&1);
156 assert_eq!(removed, Some(0));
157 assert_eq!(supply.len(), 0);
158 assert_eq!(supply.get(&1), None);
159 }
160
161 #[test]
162 fn test_update() {
163 let mut supply: InverseSupply<i32> = InverseSupply::new();
164
165 supply.insert(1, 0);
166 supply.update(Some(&1), 2, 0);
167
168 assert_eq!(supply.get(&1), None);
169 assert_eq!(supply.get(&2), Some(0));
170 }
171
172 #[test]
173 fn test_clear() {
174 let mut supply: InverseSupply<i32> = InverseSupply::new();
175
176 supply.insert(1, 0);
177 supply.insert(2, 1);
178 supply.insert(3, 2);
179
180 assert_eq!(supply.len(), 3);
181
182 supply.clear();
183
184 assert!(supply.is_empty());
185 }
186
187 #[test]
188 fn test_overwrite() {
189 let mut supply: InverseSupply<i32> = InverseSupply::new();
190
191 supply.insert(1, 0);
192 let old = supply.insert(1, 5);
193
194 assert_eq!(old, Some(0));
195 assert_eq!(supply.get(&1), Some(5));
196 assert_eq!(supply.len(), 1);
197 }
198
199 #[test]
200 fn test_iter() {
201 let mut supply: InverseSupply<i32> = InverseSupply::new();
202
203 supply.insert(10, 0);
204 supply.insert(20, 1);
205 supply.insert(30, 2);
206
207 let mut pairs: Vec<_> = supply.iter().map(|(&v, &i)| (v, i)).collect();
208 pairs.sort();
209
210 assert_eq!(pairs, vec![(10, 0), (20, 1), (30, 2)]);
211 }
212}