1#[cfg(feature = "serde")]
14mod serde;
15
16use std::ops::Index;
17
18pub use hashbrown::HashTable;
19use hashbrown::TryReserveError;
20
21pub struct IntTable<V> {
30 inner: HashTable<(u64, V)>,
32}
33
34impl<V> IntTable<V> {
35 pub const fn new() -> Self {
37 Self {
38 inner: HashTable::new(),
39 }
40 }
41
42 pub fn with_capacity(capacity: usize) -> Self {
44 Self {
45 inner: HashTable::with_capacity(capacity),
46 }
47 }
48
49 pub fn remove(&mut self, key: u64) -> Option<V> {
51 self.inner
52 .find_entry(key, eq(key))
53 .ok()
54 .map(|v| v.remove().0 .1)
55 }
56
57 pub fn shrink_to(&mut self, min_capacity: usize) {
60 self.inner.shrink_to(min_capacity, hasher)
61 }
62
63 pub fn shrink_to_fit(&mut self) {
65 self.inner.shrink_to_fit(hasher)
66 }
67
68 pub fn reserve(&mut self, additional: usize) {
71 self.inner.reserve(additional, hasher)
72 }
73
74 pub fn capacity(&self) -> usize {
76 self.inner.capacity()
77 }
78
79 pub fn clear(&mut self) {
81 self.inner.clear()
82 }
83
84 pub fn insert(&mut self, key: u64, value: V) -> Option<V> {
87 use hashbrown::hash_table::Entry;
88 match self.inner.entry(key, eq(key), hasher) {
89 Entry::Occupied(o) => {
90 let ((_, old_val), empty) = o.remove();
91 empty.insert((key, value));
92 Some(old_val)
93 }
94 Entry::Vacant(v) => {
95 v.insert((key, value));
96 None
97 }
98 }
99 }
100
101 pub fn try_insert(&mut self, key: u64, value: V) -> Result<&mut V, V> {
104 use hashbrown::hash_table::Entry;
105 match self.inner.entry(key, eq(key), hasher) {
106 Entry::Occupied(_) => Err(value),
107 Entry::Vacant(v) => {
108 let entry = v.insert((key, value));
109 Ok(&mut entry.into_mut().1)
110 }
111 }
112 }
113
114 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
116 self.inner.try_reserve(additional, hasher)
117 }
118
119 pub fn get(&self, key: u64) -> Option<&V> {
121 self.inner.find(key, eq(key)).map(|(_, v)| v)
122 }
123
124 pub fn get_mut(&mut self, key: u64) -> Option<&mut V> {
126 self.inner.find_mut(key, eq(key)).map(|(_, v)| v)
127 }
128
129 pub fn get_many_mut<const N: usize>(&mut self, ks: [u64; N]) -> Option<[&mut V; N]> {
135 self.inner
136 .get_many_mut(ks, |idx, (k, _)| ks[idx] == *k)
137 .map(|a| a.map(|(_, v)| v))
138 }
139
140 pub unsafe fn get_many_unchecked_mut<const N: usize>(
151 &mut self,
152 ks: [u64; N],
153 ) -> Option<[&mut V; N]> {
154 self.inner
155 .get_many_unchecked_mut(ks, |idx, (k, _)| ks[idx] == *k)
156 .map(|a| a.map(|(_, v)| v))
157 }
158
159 pub fn retain<F>(&mut self, mut p: F)
161 where
162 F: FnMut(&u64, &mut V) -> bool,
163 {
164 self.inner.retain(|(key, val)| p(&*key, val))
165 }
166
167 pub fn keys(&self) -> impl Iterator<Item = &u64> {
169 self.inner.iter().map(|(key, _)| key)
170 }
171
172 pub fn values(&self) -> impl Iterator<Item = &V> {
174 self.inner.iter().map(|(_, val)| val)
175 }
176
177 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
179 self.inner.iter_mut().map(|(_, val)| val)
180 }
181
182 pub fn contains_key(&self, key: u64) -> bool {
184 self.get(key).is_some()
185 }
186
187 pub fn entry(&mut self, key: u64) -> Entry<V> {
189 match self.inner.entry(key, eq(key), hasher) {
190 hashbrown::hash_table::Entry::Occupied(o) => Entry::Occupied(OccupiedEntry(o)),
191 hashbrown::hash_table::Entry::Vacant(v) => Entry::Vacant(VacantEntry(v, key)),
192 }
193 }
194
195 pub fn len(&self) -> usize {
197 self.inner.len()
198 }
199
200 pub fn is_empty(&self) -> bool {
202 self.inner().len() == 0
203 }
204
205 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&u64, &mut V)> {
208 self.inner.iter_mut().map(|(key, val)| (&*key, val))
209 }
210
211 pub fn drain(&mut self) -> impl Iterator<Item = (u64, V)> + '_ {
213 self.inner.drain()
214 }
215
216 pub fn iter(&self) -> impl Iterator<Item = (&u64, &V)> {
218 self.inner().iter().map(|(k, v)| (k, v))
219 }
220
221 pub fn extract_if<F>(&mut self, mut f: F) -> ExtractIf<'_, V, impl FnMut(&mut (u64, V)) -> bool>
230 where
231 F: FnMut(&u64, &mut V) -> bool,
232 {
233 ExtractIf(self.inner.extract_if(move |(k, v)| f(&*k, v)))
234 }
235
236 pub fn into_keys(self) -> impl Iterator<Item = u64> {
238 self.into_iter().map(|(k, _)| k)
239 }
240
241 pub fn into_values(self) -> impl Iterator<Item = V> {
243 self.into_iter().map(|(_, v)| v)
244 }
245}
246
247impl<V> FromIterator<(u64, V)> for IntTable<V> {
248 fn from_iter<T: IntoIterator<Item = (u64, V)>>(iter: T) -> Self {
251 let mut res = Self::new();
252 res.extend(iter);
253 res
254 }
255}
256
257impl<V> Default for IntTable<V> {
258 fn default() -> Self {
259 Self::new()
260 }
261}
262
263impl<V> IntoIterator for IntTable<V> {
264 type Item = (u64, V);
265
266 type IntoIter = IntTableIter<Self::Item>;
267
268 fn into_iter(self) -> Self::IntoIter {
269 let it = self.inner.into_iter();
270 IntTableIter(it)
271 }
272}
273
274impl<V> Index<u64> for IntTable<V> {
275 type Output = V;
276
277 fn index(&self, index: u64) -> &Self::Output {
278 self.get(index).expect("Key not in map")
279 }
280}
281
282impl<V> IntTable<V> {
283 pub fn inner(&self) -> &HashTable<(u64, V)> {
285 &self.inner
286 }
287
288 pub fn into_inner(self) -> HashTable<(u64, V)> {
290 self.inner
291 }
292}
293
294pub struct ExtractIf<'a, T, F: FnMut(&mut (u64, T)) -> bool>(
296 ::hashbrown::hash_table::ExtractIf<'a, (u64, T), F>,
297);
298
299impl<V, F> Iterator for ExtractIf<'_, V, F>
300where
301 F: FnMut(&mut (u64, V)) -> bool,
302{
303 type Item = (u64, V);
304
305 fn next(&mut self) -> Option<Self::Item> {
306 self.0.next()
307 }
308
309 fn size_hint(&self) -> (usize, Option<usize>) {
310 self.0.size_hint()
311 }
312}
313
314#[derive(Debug)]
316pub enum Entry<'a, V> {
317 Occupied(OccupiedEntry<'a, V>),
319 Vacant(VacantEntry<'a, V>),
321}
322
323impl<'a, V> Entry<'a, V> {
324 pub fn or_insert(self, default: V) -> &'a mut V {
327 match self {
328 Entry::Occupied(o) => o.into_mut(),
329 Entry::Vacant(v) => v.insert(default),
330 }
331 }
332
333 pub fn or_insert_with<F>(self, default: F) -> &'a mut V
336 where
337 F: FnOnce() -> V,
338 {
339 match self {
340 Entry::Occupied(o) => o.into_mut(),
341 Entry::Vacant(v) => v.insert(default()),
342 }
343 }
344
345 pub fn or_insert_with_key<F>(self, default: F) -> &'a mut V
348 where
349 F: FnOnce(&u64) -> V,
350 {
351 match self {
352 Entry::Occupied(o) => o.into_mut(),
353 Entry::Vacant(v) => {
354 let key = v.1;
355 v.insert(default(&key))
356 }
357 }
358 }
359
360 pub fn key(&self) -> &u64 {
362 match self {
363 Entry::Occupied(o) => &o.0.get().0,
364 Entry::Vacant(v) => &v.1,
365 }
366 }
367
368 pub fn and_modify<F>(mut self, f: F) -> Self
371 where
372 F: FnOnce(&mut V),
373 {
374 if let Entry::Occupied(o) = &mut self {
375 f(o.get_mut())
376 };
377 self
378 }
379
380 pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, V> {
382 match self {
383 Entry::Occupied(mut o) => {
384 o.insert(value);
385 o
386 }
387 Entry::Vacant(v) => v.insert_entry(value),
388 }
389 }
390}
391
392impl<'a, V> Entry<'a, V>
393where
394 V: Default,
395{
396 pub fn or_default(self) -> &'a mut V {
398 #[allow(clippy::unwrap_or_default)] self.or_insert(V::default())
400 }
401}
402
403#[derive(Debug)]
405pub struct OccupiedEntry<'a, V>(::hashbrown::hash_table::OccupiedEntry<'a, (u64, V)>);
406#[derive(Debug)]
408pub struct VacantEntry<'a, V>(::hashbrown::hash_table::VacantEntry<'a, (u64, V)>, u64);
409
410impl<'a, V> OccupiedEntry<'a, V> {
411 pub fn get(&self) -> &V {
413 &self.0.get().1
414 }
415
416 pub fn get_mut(&mut self) -> &mut V {
418 &mut self.0.get_mut().1
419 }
420
421 pub fn insert(&mut self, new_val: V) -> V {
423 std::mem::replace(self.get_mut(), new_val)
424 }
425
426 pub fn into_mut(self) -> &'a mut V {
428 &mut self.0.into_mut().1
429 }
430
431 pub fn remove(self) -> V {
433 self.0.remove().0 .1
434 }
435
436 pub fn remove_entry(self) -> (u64, V) {
438 self.0.remove().0
439 }
440
441 pub fn key(&self) -> &u64 {
443 &self.0.get().0
444 }
445}
446
447impl<'a, V> VacantEntry<'a, V> {
448 pub fn insert(self, value: V) -> &'a mut V {
450 let key = self.1;
451 &mut self.0.insert((key, value)).into_mut().1
452 }
453
454 fn insert_entry(self, value: V) -> OccupiedEntry<'a, V> {
456 OccupiedEntry(self.0.insert((self.1, value)))
457 }
458
459 pub fn key(&self) -> &u64 {
461 &self.1
462 }
463}
464
465fn eq<V>(key: u64) -> impl Fn(&(u64, V)) -> bool {
467 move |(other_key, _)| *other_key == key
468}
469
470fn hasher<V>((key, _value): &(u64, V)) -> u64 {
472 *key
473}
474
475pub struct IntTableIter<V>(::hashbrown::hash_table::IntoIter<V>);
477impl<V> ExactSizeIterator for IntTableIter<V> {}
478
479impl<V> Iterator for IntTableIter<V> {
480 fn size_hint(&self) -> (usize, Option<usize>) {
481 let l = self.0.len();
482 (l, Some(l))
483 }
484
485 fn count(self) -> usize
486 where
487 Self: Sized,
488 {
489 self.len()
490 }
491
492 type Item = V;
493
494 fn next(&mut self) -> Option<Self::Item> {
495 self.0.next()
496 }
497}
498
499impl<V> Extend<(u64, V)> for IntTable<V> {
500 fn extend<T: IntoIterator<Item = (u64, V)>>(&mut self, iter: T) {
501 let iter = iter.into_iter();
502 let (min, max) = iter.size_hint();
503 self.reserve(max.unwrap_or(min));
504 for (k, v) in iter {
505 self.insert(k, v);
506 }
507 }
508}
509
510impl<V> PartialEq for IntTable<V>
511where
512 V: PartialEq,
513{
514 fn eq(&self, other: &IntTable<V>) -> bool {
515 self.iter().eq(other.iter())
516 }
517}
518
519impl<V> std::fmt::Debug for IntTable<V>
520where
521 V: std::fmt::Debug,
522{
523 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
524 let mut map_debug = fmt.debug_map();
525 for (k, v) in self.iter() {
526 map_debug.key(k);
527 map_debug.value(v);
528 }
529
530 map_debug.finish()
531 }
532}