1use crate::Map;
2use smallvec::{SmallVec, smallvec};
3use std::{
4 cell::Cell,
5 hash::{DefaultHasher, Hash, Hasher},
6 iter, mem, ops,
7};
8
9#[derive(Debug, Clone)]
17pub struct UniqueContainer<T> {
18 values: Values<T>,
19
20 map: Map<u64, SmallVec<[usize; 1]>>,
22}
23
24impl<T> UniqueContainer<T> {
25 pub fn new() -> Self {
26 Self {
27 values: Values::new(),
28 map: Map::default(),
29 }
30 }
31
32 pub const fn len(&self) -> usize {
33 self.values.len()
34 }
35
36 pub const fn is_empty(&self) -> bool {
37 self.len() == 0
38 }
39
40 pub fn get(&self, index: usize) -> Option<&T> {
41 self.values.get(index)
42 }
43
44 pub fn iter(&self) -> PairIter<T> {
45 self.values.iter()
46 }
47
48 pub fn values(&self) -> ValueIter<T> {
49 self.values.values()
50 }
51
52 pub fn clear(&mut self) {
53 self.values.clear();
54 self.map.clear();
55 }
56}
57
58impl<T> UniqueContainer<T>
59where
60 T: Hash + Eq + std::fmt::Debug, {
62 pub fn insert(&mut self, value: T) -> usize {
67 let hash = Self::hash(&value);
68 if let Some(index) = self._find(hash, &value) {
69 self.values.replace(index, Value::Data(value));
70 return index;
71 }
72
73 let index = self.values.len();
74
75 Self::append_mapping(&mut self.map, hash, index);
76 self.values.push(Value::Data(value));
77
78 index
79 }
80
81 pub fn next_index<Q>(&mut self, value: &Q) -> usize
82 where
83 Q: Hash + PartialEq<T> + ?Sized,
84 {
85 self.find(value).unwrap_or(self.values.len())
86 }
87
88 pub fn replace<Q>(&mut self, old: &Q, new: T) -> bool
89 where
90 Q: Hash + PartialEq<T> + ?Sized,
91 {
92 if let Some(index) = self.find(old) {
93 self.replace_at(index, new);
94 true
95 } else {
96 false
97 }
98 }
99
100 fn replace_at(&mut self, index: usize, value: T) {
110 let hash = Self::hash(&value);
111
112 if let Some(exist_idx) = self._find(hash, &value) {
113 self.values
114 .replace(index, Value::Indirect(Cell::new(exist_idx)));
115 self.values.replace(exist_idx, Value::Data(value));
116 } else {
117 Self::append_mapping(&mut self.map, hash, index);
118 let old = self.values.replace(index, Value::Data(value));
119 if let Value::Data(old) = old {
120 Self::remove_mapping(&mut self.map, Self::hash(&old), index);
121 }
122 }
123 }
124
125 pub fn find<Q>(&self, value: &Q) -> Option<usize>
126 where
127 Q: Hash + PartialEq<T> + ?Sized,
128 {
129 let hash = Self::hash(value);
130 self._find(hash, value)
131 }
132
133 fn _find<Q>(&self, hash: u64, value: &Q) -> Option<usize>
138 where
139 Q: PartialEq<T> + ?Sized,
140 {
141 if let Some(idxs) = self.map.get(&hash) {
142 for idx in idxs.iter() {
143 if value == &self.values[*idx] {
144 return Some(*idx);
145 }
146 }
147 }
148 None
149 }
150
151 fn hash<Q>(value: &Q) -> u64
152 where
153 Q: Hash + PartialEq<T> + ?Sized,
154 {
155 let mut hasher = DefaultHasher::new();
156 value.hash(&mut hasher);
157 hasher.finish()
158 }
159
160 fn append_mapping(map: &mut Map<u64, SmallVec<[usize; 1]>>, hash: u64, index: usize) {
161 map.entry(hash)
162 .and_modify(|indices| indices.push(index))
163 .or_insert(smallvec![index]);
164 }
165
166 fn remove_mapping(map: &mut Map<u64, SmallVec<[usize; 1]>>, hash: u64, index: usize) {
167 let Some(indices) = map.get_mut(&hash) else {
168 return;
169 };
170
171 let Some((i, _)) = indices.iter().enumerate().find(|(_, ii)| **ii == index) else {
172 return;
173 };
174
175 indices.swap_remove(i);
176
177 if indices.is_empty() {
178 map.remove(&hash);
179 }
180 }
181}
182
183impl<T> ops::Index<usize> for UniqueContainer<T> {
184 type Output = T;
185
186 fn index(&self, index: usize) -> &Self::Output {
187 &self.values[index]
188 }
189}
190
191impl<T> Default for UniqueContainer<T> {
192 fn default() -> Self {
193 Self::new()
194 }
195}
196
197#[derive(Debug, Clone)]
198struct Values<T>(Vec<Value<T>>);
199
200impl<T> Values<T> {
201 const fn new() -> Self {
202 Self(Vec::new())
203 }
204
205 const fn len(&self) -> usize {
206 self.0.len()
207 }
208
209 fn iter(&self) -> PairIter<T> {
210 PairIter::new(self)
211 }
212
213 fn values(&self) -> ValueIter<T> {
214 ValueIter::new(self)
215 }
216
217 fn get(&self, index: usize) -> Option<&T> {
218 self.get_with_opt(index).map(|(_idx, ty)| ty)
219 }
220
221 fn get_with_opt(&self, index: usize) -> Option<(usize, &T)> {
222 match self.0.get(index)? {
223 Value::Indirect(v) => {
224 let (w, ty) = self.get_with_opt(v.get())?;
225 v.set(w);
226 Some((w, ty))
227 }
228 Value::Data(ty) => Some((index, ty)),
229 }
230 }
231
232 fn replace(&mut self, index: usize, value: Value<T>) -> Value<T> {
233 mem::replace(&mut self.0[index], value)
234 }
235
236 fn push(&mut self, value: Value<T>) {
237 self.0.push(value);
238 }
239
240 fn clear(&mut self) {
241 self.0.clear();
242 }
243}
244
245impl<T> ops::Index<usize> for Values<T> {
246 type Output = T;
247
248 fn index(&self, index: usize) -> &Self::Output {
249 self.get(index).expect("index is out of bounds")
250 }
251}
252
253#[derive(Debug, Clone)]
254enum Value<T> {
255 Indirect(Cell<usize>),
256 Data(T),
257}
258
259#[derive(Clone)]
261pub struct PairIter<'a, T> {
262 values: &'a [Value<T>],
263 cur: usize,
264 remain: usize,
265}
266
267impl<'a, T> PairIter<'a, T> {
268 fn new(values: &'a Values<T>) -> Self {
269 Self {
270 values: values.0.as_slice(),
271 cur: 0,
272 remain: values
273 .0
274 .iter()
275 .filter(|value| matches!(value, Value::Data(_)))
276 .count(),
277 }
278 }
279
280 const fn len(&self) -> usize {
281 self.remain
282 }
283}
284
285impl<'a, T> Iterator for PairIter<'a, T> {
286 type Item = (usize, &'a T);
287
288 fn next(&mut self) -> Option<Self::Item> {
289 if self.remain == 0 {
290 return None;
291 }
292
293 let value = loop {
294 let value = &self.values[self.cur];
295 self.cur += 1;
296 match value {
297 Value::Indirect(_) => continue,
298 Value::Data(value) => break value,
299 }
300 };
301 self.remain -= 1;
302 Some((self.cur - 1, value))
303 }
304
305 fn size_hint(&self) -> (usize, Option<usize>) {
306 let len = <Self>::len(self);
307 (len, Some(len))
308 }
309}
310
311impl<T> ExactSizeIterator for PairIter<'_, T> {
312 fn len(&self) -> usize {
313 <Self>::len(self)
314 }
315}
316
317impl<T> iter::FusedIterator for PairIter<'_, T> {}
318
319#[derive(Clone)]
321pub struct ValueIter<'a, T> {
322 rest: &'a [Value<T>],
323 remain: usize,
324}
325
326impl<'a, T> ValueIter<'a, T> {
327 fn new(values: &'a Values<T>) -> Self {
328 Self {
329 rest: values.0.as_slice(),
330 remain: values
331 .0
332 .iter()
333 .filter(|value| matches!(value, Value::Data(_)))
334 .count(),
335 }
336 }
337
338 const fn len(&self) -> usize {
339 self.remain
340 }
341}
342
343impl<'a, T> Iterator for ValueIter<'a, T> {
344 type Item = &'a T;
345
346 fn next(&mut self) -> Option<Self::Item> {
347 let value = loop {
348 let (head, rest) = self.rest.split_first()?;
349 self.rest = rest;
350 match head {
351 Value::Indirect(_) => continue,
352 Value::Data(value) => break value,
353 }
354 };
355 self.remain -= 1;
356 Some(value)
357 }
358
359 fn size_hint(&self) -> (usize, Option<usize>) {
360 let len = <Self>::len(self);
361 (len, Some(len))
362 }
363}
364
365impl<T> ExactSizeIterator for ValueIter<'_, T> {
366 fn len(&self) -> usize {
367 <Self>::len(self)
368 }
369}
370
371impl<T> iter::FusedIterator for ValueIter<'_, T> {}