1use super::{Entry, Key};
2use core::hash::{BuildHasher, Hash};
3use hashbrown::hash_table::Entry as TableEntry;
4use hashbrown::{DefaultHashBuilder, HashTable};
5
6pub trait Equivalent<K: ?Sized> {
12 fn equivalent(&self, key: &K) -> bool;
14}
15
16impl<Q: ?Sized + Eq, K: ?Sized> Equivalent<K> for Q
17where
18 K: std::borrow::Borrow<Q>,
19{
20 fn equivalent(&self, key: &K) -> bool {
21 self == key.borrow()
22 }
23}
24
25fn equivalent_key<'a, Q>(entries: &'a [Entry], k: &'a Q) -> impl 'a + Fn(&Indexes) -> bool
26where
27 Q: ?Sized + Equivalent<Key>,
28{
29 move |indexes| k.equivalent(&entries[indexes.rep].key)
30}
31
32fn make_hasher() -> impl Fn(&Indexes) -> u64 {
33 |indexes| indexes.hash
34}
35
36#[derive(Clone, Debug)]
37pub struct Indexes {
38 rep: usize,
40
41 other: Vec<usize>,
43
44 hash: u64,
47}
48
49impl PartialEq for Indexes {
50 fn eq(&self, other: &Self) -> bool {
51 self.rep == other.rep && self.other == other.other
52 }
53}
54
55impl Eq for Indexes {}
56
57impl Indexes {
58 const fn new(rep: usize, hash: u64) -> Self {
59 Self {
60 rep,
61 other: Vec::new(),
62 hash,
63 }
64 }
65
66 pub fn len(&self) -> usize {
67 1 + self.other.len()
68 }
69
70 pub const fn first(&self) -> usize {
71 self.rep
72 }
73
74 pub fn is_redundant(&self) -> bool {
75 !self.other.is_empty()
76 }
77
78 pub fn redundant(&self) -> Option<usize> {
79 self.other.first().copied()
80 }
81
82 pub fn redundants(&self) -> &[usize] {
83 &self.other
84 }
85
86 fn insert(&mut self, mut index: usize) {
87 if index != self.rep {
88 if index < self.rep {
89 core::mem::swap(&mut index, &mut self.rep);
90 }
91
92 if let Err(i) = self.other.binary_search(&index) {
93 self.other.insert(i, index)
94 }
95 }
96 }
97
98 fn remove(&mut self, index: usize) -> bool {
103 if self.rep == index {
104 if self.other.is_empty() {
105 false
106 } else {
107 self.rep = self.other.remove(0);
108 true
109 }
110 } else {
111 if let Ok(i) = self.other.binary_search(&index) {
112 self.other.remove(i);
113 }
114
115 true
116 }
117 }
118
119 pub fn shift_down(&mut self, index: usize) {
121 if self.rep > index {
122 self.rep -= 1
123 }
124
125 for i in &mut self.other {
126 if *i > index {
127 *i -= 1
128 }
129 }
130 }
131
132 pub fn shift_up(&mut self, index: usize) {
134 if self.rep >= index {
135 self.rep += 1
136 }
137
138 for i in &mut self.other {
139 if *i >= index {
140 *i += 1
141 }
142 }
143 }
144
145 pub fn iter(&self) -> super::Indexes<'_> {
146 super::Indexes::Some {
147 first: Some(self.rep),
148 other: self.other.iter(),
149 }
150 }
151}
152
153impl<'a> IntoIterator for &'a Indexes {
154 type Item = usize;
155 type IntoIter = super::Indexes<'a>;
156
157 fn into_iter(self) -> Self::IntoIter {
158 self.iter()
159 }
160}
161
162#[derive(Clone)]
163pub struct IndexMap<S = DefaultHashBuilder> {
164 hash_builder: S,
165 table: HashTable<Indexes>,
166}
167
168impl<S: Default> Default for IndexMap<S> {
169 fn default() -> Self {
170 Self {
171 hash_builder: S::default(),
172 table: HashTable::new(),
173 }
174 }
175}
176
177impl<S> IndexMap<S> {
178 pub fn new() -> Self
179 where
180 S: Default,
181 {
182 Self::default()
183 }
184
185 pub fn with_capacity(capacity: usize) -> Self
186 where
187 S: Default,
188 {
189 Self {
190 hash_builder: S::default(),
191 table: HashTable::with_capacity(capacity),
192 }
193 }
194
195 pub fn contains_duplicate_keys(&self) -> bool {
196 self.table.iter().any(Indexes::is_redundant)
197 }
198}
199
200impl<S: BuildHasher> IndexMap<S> {
201 pub fn get<Q>(&self, entries: &[Entry], key: &Q) -> Option<&Indexes>
202 where
203 Q: ?Sized + Hash + Equivalent<Key>,
204 {
205 let hash = self.hash_builder.hash_one(key);
206 self.table.find(hash, equivalent_key(entries, key))
207 }
208
209 pub fn insert(&mut self, entries: &[Entry], index: usize) -> bool {
216 let key = &entries[index].key;
217 let hash = self.hash_builder.hash_one(key);
218 match self
219 .table
220 .entry(hash, equivalent_key(entries, key), make_hasher())
221 {
222 TableEntry::Occupied(mut occupied) => {
223 occupied.get_mut().insert(index);
224 false
225 }
226 TableEntry::Vacant(vacant) => {
227 vacant.insert(Indexes::new(index, hash));
228 true
229 }
230 }
231 }
232
233 pub fn lookup_or_insert<Q>(
239 &mut self,
240 entries: &[Entry],
241 new_index: usize,
242 key: &Q,
243 ) -> Option<usize>
244 where
245 Q: ?Sized + Hash + Equivalent<Key>,
246 {
247 let hash = self.hash_builder.hash_one(key);
248 match self
249 .table
250 .entry(hash, equivalent_key(entries, key), make_hasher())
251 {
252 TableEntry::Occupied(occupied) => Some(occupied.get().first()),
253 TableEntry::Vacant(vacant) => {
254 vacant.insert(Indexes::new(new_index, hash));
255 None
256 }
257 }
258 }
259
260 pub fn remove(&mut self, entries: &[Entry], index: usize) {
262 let key = &entries[index].key;
263 let hash = self.hash_builder.hash_one(key);
264 if let Ok(mut occupied) = self.table.find_entry(hash, equivalent_key(entries, key)) {
265 if !occupied.get_mut().remove(index) {
266 occupied.remove();
267 }
268 }
269 }
270
271 pub fn shift_down(&mut self, index: usize) {
273 for indexes in self.table.iter_mut() {
274 indexes.shift_down(index);
275 }
276 }
277
278 pub fn shift_up(&mut self, index: usize) {
280 for indexes in self.table.iter_mut() {
281 indexes.shift_up(index);
282 }
283 }
284
285 pub fn rebuild_sorted(&mut self, entries: &[Entry]) {
297 self.table.clear();
298 self.table.reserve(entries.len(), make_hasher());
299
300 let mut run_start = 0;
301 while run_start < entries.len() {
302 let key = &entries[run_start].key;
303 let mut run_end = run_start + 1;
304 while run_end < entries.len() && entries[run_end].key == *key {
305 run_end += 1;
306 }
307
308 let hash = self.hash_builder.hash_one(key);
309 let mut indexes = Indexes::new(run_start, hash);
310 indexes.other.reserve_exact(run_end - run_start - 1);
311 indexes.other.extend(run_start + 1..run_end);
312 self.table.insert_unique(hash, indexes, make_hasher());
313
314 run_start = run_end;
315 }
316 }
317}
318
319#[cfg(test)]
320mod tests {
321 use super::*;
322 use crate::Value;
323
324 #[test]
325 fn insert() {
326 let entries = [
327 Entry::new("a".into(), Value::Null),
328 Entry::new("b".into(), Value::Null),
329 Entry::new("a".into(), Value::Null),
330 ];
331
332 let mut indexes: IndexMap = IndexMap::default();
333 indexes.insert(&entries, 2);
334 indexes.insert(&entries, 1);
335 indexes.insert(&entries, 0);
336
337 let mut a = indexes.get(&entries, "a").unwrap().iter();
338 let mut b = indexes.get(&entries, "b").unwrap().iter();
339
340 assert_eq!(a.next(), Some(0));
341 assert_eq!(a.next(), Some(2));
342 assert_eq!(a.next(), None);
343 assert_eq!(b.next(), Some(1));
344 assert_eq!(b.next(), None);
345 assert_eq!(indexes.get(&entries, "c"), None)
346 }
347
348 #[test]
349 fn remove1() {
350 let entries = [
351 Entry::new("a".into(), Value::Null),
352 Entry::new("b".into(), Value::Null),
353 Entry::new("a".into(), Value::Null),
354 ];
355
356 let mut indexes: IndexMap = IndexMap::default();
357 indexes.insert(&entries, 2);
358 indexes.insert(&entries, 1);
359 indexes.insert(&entries, 0);
360
361 indexes.remove(&entries, 1);
362 indexes.remove(&entries, 0);
363
364 let mut a = indexes.get(&entries, "a").unwrap().iter();
365
366 assert_eq!(a.next(), Some(2));
367 assert_eq!(a.next(), None);
368 assert_eq!(indexes.get(&entries, "b"), None)
369 }
370
371 #[test]
372 fn remove2() {
373 let entries = [
374 Entry::new("a".into(), Value::Null),
375 Entry::new("b".into(), Value::Null),
376 Entry::new("a".into(), Value::Null),
377 ];
378
379 let mut indexes: IndexMap = IndexMap::default();
380 indexes.insert(&entries, 2);
381 indexes.insert(&entries, 1);
382 indexes.insert(&entries, 0);
383
384 indexes.remove(&entries, 0);
385 indexes.remove(&entries, 1);
386 indexes.remove(&entries, 2);
387
388 assert_eq!(indexes.get(&entries, "a"), None);
389 assert_eq!(indexes.get(&entries, "b"), None)
390 }
391}