1use crate::prelude::*;
4use alloc::slice::Iter;
5use core::hash::Hash;
6use core::ops::{Bound, RangeBounds};
7
8#[derive(Clone, Debug, Eq)]
26pub struct IndexedMap<K: Hash + Ord, V> {
27 map: HashMap<K, V>,
28 keys: Vec<K>,
29}
30
31impl<K: Clone + Hash + Ord, V> IndexedMap<K, V> {
32 pub fn new() -> Self {
34 Self { map: new_hash_map(), keys: Vec::new() }
35 }
36
37 pub fn with_capacity(capacity: usize) -> Self {
39 Self { map: hash_map_with_capacity(capacity), keys: Vec::with_capacity(capacity) }
40 }
41
42 #[inline(always)]
43 pub fn get(&self, key: &K) -> Option<&V> {
45 self.map.get(key)
46 }
47
48 pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
50 self.map.get_mut(key)
51 }
52
53 pub fn get_key_value(&self, key: &K) -> Option<(&K, &V)> {
55 self.map.get_key_value(key)
56 }
57
58 #[inline]
59 pub fn contains_key(&self, key: &K) -> bool {
61 self.map.contains_key(key)
62 }
63
64 pub fn remove(&mut self, key: &K) -> Option<V> {
66 let ret = self.map.remove(key);
67 if let Some(_) = ret {
68 let idx =
69 self.keys.iter().position(|k| k == key).expect("map and keys must be consistent");
70 self.keys.remove(idx);
71 }
72 ret
73 }
74
75 pub fn remove_fetch_bulk(&mut self, keys: &HashSet<K>) -> Vec<(K, V)> {
77 let mut res = Vec::with_capacity(keys.len());
78 for key in keys.iter() {
79 if let Some((k, v)) = self.map.remove_entry(key) {
80 res.push((k, v));
81 }
82 }
83 self.keys.retain(|k| !keys.contains(k));
84 res
85 }
86
87 pub fn remove_bulk(&mut self, keys: &HashSet<K>) {
89 for key in keys.iter() {
90 self.map.remove(key);
91 }
92 self.keys.retain(|k| !keys.contains(k));
93 }
94
95 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
98 let ret = self.map.insert(key.clone(), value);
99 if ret.is_none() {
100 self.keys.push(key);
101 }
102 ret
103 }
104
105 pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
107 match self.map.entry(key.clone()) {
108 hash_map::Entry::Vacant(entry) => {
109 Entry::Vacant(VacantEntry { underlying_entry: entry, key, keys: &mut self.keys })
110 },
111 hash_map::Entry::Occupied(entry) => {
112 Entry::Occupied(OccupiedEntry { underlying_entry: entry, keys: &mut self.keys })
113 },
114 }
115 }
116
117 pub fn unordered_keys(&self) -> impl Iterator<Item = &K> {
119 self.map.keys()
120 }
121
122 pub fn unordered_iter(&self) -> impl Iterator<Item = (&K, &V)> {
124 self.map.iter()
125 }
126
127 pub fn unordered_iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
130 self.map.iter_mut()
131 }
132
133 pub fn range<R: RangeBounds<K>>(&mut self, range: R) -> Range<'_, K, V> {
135 self.keys.sort_unstable();
136 let start = match range.start_bound() {
137 Bound::Unbounded => 0,
138 Bound::Included(key) => self.keys.binary_search(key).unwrap_or_else(|index| index),
139 Bound::Excluded(key) => {
140 self.keys.binary_search(key).map(|index| index + 1).unwrap_or_else(|index| index)
141 },
142 };
143 let end = match range.end_bound() {
144 Bound::Unbounded => self.keys.len(),
145 Bound::Included(key) => {
146 self.keys.binary_search(key).map(|index| index + 1).unwrap_or_else(|index| index)
147 },
148 Bound::Excluded(key) => self.keys.binary_search(key).unwrap_or_else(|index| index),
149 };
150
151 Range { inner_range: self.keys[start..end].iter(), map: &self.map }
152 }
153
154 pub fn len(&self) -> usize {
156 self.map.len()
157 }
158
159 pub fn is_empty(&self) -> bool {
161 self.map.is_empty()
162 }
163}
164
165impl<K: Hash + Ord + PartialEq, V: PartialEq> PartialEq for IndexedMap<K, V> {
166 fn eq(&self, other: &Self) -> bool {
167 self.map == other.map
168 }
169}
170
171pub struct Range<'a, K: Hash + Ord, V> {
175 inner_range: Iter<'a, K>,
176 map: &'a HashMap<K, V>,
177}
178impl<'a, K: Hash + Ord, V: 'a> Iterator for Range<'a, K, V> {
179 type Item = (&'a K, &'a V);
180 fn next(&mut self) -> Option<(&'a K, &'a V)> {
181 self.inner_range
182 .next()
183 .map(|k| (k, self.map.get(k).expect("map and keys must be consistent")))
184 }
185}
186
187pub struct VacantEntry<'a, K: Hash + Ord, V> {
191 underlying_entry: VacantHashMapEntry<'a, K, V>,
192 key: K,
193 keys: &'a mut Vec<K>,
194}
195
196pub struct OccupiedEntry<'a, K: Hash + Ord, V> {
200 underlying_entry: OccupiedHashMapEntry<'a, K, V>,
201 keys: &'a mut Vec<K>,
202}
203
204pub enum Entry<'a, K: Hash + Ord, V> {
209 Vacant(VacantEntry<'a, K, V>),
211 Occupied(OccupiedEntry<'a, K, V>),
213}
214
215impl<'a, K: Hash + Ord, V> VacantEntry<'a, K, V> {
216 pub fn insert(self, value: V) -> &'a mut V {
218 self.keys.push(self.key);
219 self.underlying_entry.insert(value)
220 }
221}
222
223impl<'a, K: Hash + Ord, V> OccupiedEntry<'a, K, V> {
224 pub fn remove_entry(self) -> (K, V) {
226 let res = self.underlying_entry.remove_entry();
227 let idx =
228 self.keys.iter().position(|k| k == &res.0).expect("map and keys must be consistent");
229 self.keys.remove(idx);
230 res
231 }
232
233 pub fn key(&self) -> &K {
235 self.underlying_entry.key()
236 }
237
238 pub fn get(&self) -> &V {
240 self.underlying_entry.get()
241 }
242
243 pub fn get_mut(&mut self) -> &mut V {
245 self.underlying_entry.get_mut()
246 }
247
248 pub fn into_mut(self) -> &'a mut V {
251 self.underlying_entry.into_mut()
252 }
253}