datex_core/utils/
freemap.rs1use std::collections::HashMap;
2use std::collections::hash_map::{Iter, IterMut};
3
4pub trait NextKey: Copy + Eq + std::hash::Hash + Default {
5 fn next_key(&mut self) -> Self;
6}
7
8pub struct FreeHashMap<K: NextKey, T> {
10 entries: HashMap<K, T>,
11 free_list: Vec<K>,
12 next_id: K,
13}
14
15impl<K: NextKey, T> Default for FreeHashMap<K, T> {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21impl<K: NextKey, T> FreeHashMap<K, T> {
22 pub fn new() -> Self {
23 Self {
24 entries: HashMap::new(),
25 free_list: Vec::new(),
26 next_id: K::default(),
27 }
28 }
29
30 pub fn clear(&mut self) {
31 self.entries.clear();
32 self.free_list.clear();
33 self.next_id = K::default();
34 }
35
36 pub fn add(&mut self, value: T) -> K {
38 if let Some(id) = self.free_list.pop() {
39 self.entries.insert(id, value);
40 id
41 } else {
42 let id = self.next_id.next_key();
43 self.entries.insert(id, value);
44 id
45 }
46 }
47
48 pub fn has_value(&self, value: &T) -> bool
50 where
51 T: PartialEq,
52 {
53 self.entries.values().any(|v| v == value)
54 }
55
56 pub fn get_id(&self, value: &T) -> Option<K>
58 where
59 T: PartialEq,
60 {
61 for (k, v) in &self.entries {
62 if v == value {
63 return Some(*k);
64 }
65 }
66 None
67 }
68
69 pub fn len(&self) -> usize {
71 self.entries.len()
72 }
73
74 pub fn is_empty(&self) -> bool {
75 self.entries.is_empty()
76 }
77
78 pub fn has(&self, id: &K) -> bool {
80 self.entries.contains_key(id)
81 }
82
83 pub fn remove(&mut self, id: K) -> Option<T> {
85 let cur = self.entries.remove(&id);
86 if cur.is_some() {
87 self.free_list.push(id);
88 }
89 cur
90 }
91
92 pub fn get(&self, id: &K) -> Option<&T> {
94 self.entries.get(id)
95 }
96
97 pub fn get_mut(&mut self, id: &K) -> Option<&mut T> {
99 self.entries.get_mut(id)
100 }
101
102 pub fn values(&self) -> impl Iterator<Item = &T> {
103 self.entries.values()
104 }
105 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
106 self.entries.values_mut()
107 }
108 pub fn keys(&self) -> impl Iterator<Item = &K> {
109 self.entries.keys()
110 }
111
112 pub fn iter(&self) -> Iter<'_, K, T> {
113 self.entries.iter()
114 }
115
116 pub fn iter_mut(&mut self) -> IterMut<'_, K, T> {
117 self.entries.iter_mut()
118 }
119}
120
121impl<K: NextKey, T> IntoIterator for FreeHashMap<K, T> {
122 type Item = (K, T);
123 type IntoIter = std::collections::hash_map::IntoIter<K, T>;
124
125 fn into_iter(self) -> Self::IntoIter {
126 self.entries.into_iter()
127 }
128}
129
130impl<'a, K: NextKey, T> IntoIterator for &'a FreeHashMap<K, T> {
131 type Item = (&'a K, &'a T);
132 type IntoIter = Iter<'a, K, T>;
133
134 fn into_iter(self) -> Self::IntoIter {
135 self.entries.iter()
136 }
137}
138
139impl<'a, K: NextKey, T> IntoIterator for &'a mut FreeHashMap<K, T> {
140 type Item = (&'a K, &'a mut T);
141 type IntoIter = IterMut<'a, K, T>;
142
143 fn into_iter(self) -> Self::IntoIter {
144 self.entries.iter_mut()
145 }
146}
147
148impl NextKey for u32 {
149 fn next_key(&mut self) -> Self {
150 let current = *self;
151 *self = self.wrapping_add(1);
152 current
153 }
154}