1use super::{Entry, Key};
2use core::hash::{BuildHasher, Hash};
3use hashbrown::hash_map::DefaultHashBuilder;
4use hashbrown::raw::RawTable;
5
6pub trait Equivalent<K: ?Sized> {
7 fn equivalent(&self, key: &K) -> bool;
8}
9
10impl<Q: ?Sized + Eq, K: ?Sized> Equivalent<K> for Q
11where
12 K: std::borrow::Borrow<Q>,
13{
14 fn equivalent(&self, key: &K) -> bool {
15 self == key.borrow()
16 }
17}
18
19fn equivalent_key<'a, Q>(entries: &'a [Entry], k: &'a Q) -> impl 'a + Fn(&Indexes) -> bool
20where
21 Q: ?Sized + Equivalent<Key>,
22{
23 move |indexes| k.equivalent(&entries[indexes.rep].key)
24}
25
26fn make_hasher<'a, S>(entries: &'a [Entry], hash_builder: &'a S) -> impl 'a + Fn(&Indexes) -> u64
27where
28 S: BuildHasher,
29{
30 move |indexes| hash_builder.hash_one(&entries[indexes.rep].key)
31}
32
33#[derive(Clone, Debug, PartialEq, Eq)]
34pub struct Indexes {
35 rep: usize,
37
38 other: Vec<usize>,
40}
41
42impl Indexes {
43 fn new(rep: usize) -> Self {
44 Self {
45 rep,
46 other: Vec::new(),
47 }
48 }
49
50 pub fn len(&self) -> usize {
51 1 + self.other.len()
52 }
53
54 pub fn first(&self) -> usize {
55 self.rep
56 }
57
58 pub fn is_redundant(&self) -> bool {
59 !self.other.is_empty()
60 }
61
62 pub fn redundant(&self) -> Option<usize> {
63 self.other.first().cloned()
64 }
65
66 pub fn redundants(&self) -> &[usize] {
67 &self.other
68 }
69
70 fn insert(&mut self, mut index: usize) {
71 if index != self.rep {
72 if index < self.rep {
73 core::mem::swap(&mut index, &mut self.rep);
74 }
75
76 if let Err(i) = self.other.binary_search(&index) {
77 self.other.insert(i, index)
78 }
79 }
80 }
81
82 fn remove(&mut self, index: usize) -> bool {
87 if self.rep == index {
88 if self.other.is_empty() {
89 false
90 } else {
91 self.rep = self.other.remove(0);
92 true
93 }
94 } else {
95 if let Ok(i) = self.other.binary_search(&index) {
96 self.other.remove(i);
97 }
98
99 true
100 }
101 }
102
103 pub fn shift_down(&mut self, index: usize) {
105 if self.rep > index {
106 self.rep -= 1
107 }
108
109 for i in &mut self.other {
110 if *i > index {
111 *i -= 1
112 }
113 }
114 }
115
116 pub fn shift_up(&mut self, index: usize) {
118 if self.rep >= index {
119 self.rep += 1
120 }
121
122 for i in &mut self.other {
123 if *i >= index {
124 *i += 1
125 }
126 }
127 }
128
129 pub fn iter(&self) -> super::Indexes {
130 super::Indexes::Some {
131 first: Some(self.rep),
132 other: self.other.iter(),
133 }
134 }
135}
136
137impl<'a> IntoIterator for &'a Indexes {
138 type Item = usize;
139 type IntoIter = super::Indexes<'a>;
140
141 fn into_iter(self) -> Self::IntoIter {
142 self.iter()
143 }
144}
145
146#[derive(Clone)]
147pub struct IndexMap<S = DefaultHashBuilder> {
148 hash_builder: S,
149 table: RawTable<Indexes>,
150}
151
152impl<S: Default> IndexMap<S> {
153 fn default() -> Self {
154 Self {
155 hash_builder: S::default(),
156 table: RawTable::default(),
157 }
158 }
159}
160
161impl<S> IndexMap<S> {
162 pub fn new() -> Self
163 where
164 S: Default,
165 {
166 Self::default()
167 }
168
169 pub fn contains_duplicate_keys(&self) -> bool {
170 unsafe {
171 for bucket in self.table.iter() {
172 if bucket.as_ref().is_redundant() {
173 return true;
174 }
175 }
176 }
177
178 false
179 }
180}
181
182impl<S: BuildHasher> IndexMap<S> {
183 pub fn get<Q>(&self, entries: &[Entry], key: &Q) -> Option<&Indexes>
184 where
185 Q: ?Sized + Hash + Equivalent<Key>,
186 {
187 let hash = self.hash_builder.hash_one(key);
188 self.table.get(hash, equivalent_key(entries, key))
189 }
190
191 pub fn insert(&mut self, entries: &[Entry], index: usize) -> bool {
195 let key = &entries[index].key;
196 let hash = self.hash_builder.hash_one(key);
197 match self.table.get_mut(hash, equivalent_key(entries, key)) {
198 Some(indexes) => {
199 indexes.insert(index);
200 false
201 }
202 None => {
203 self.table.insert(
204 hash,
205 Indexes::new(index),
206 make_hasher::<S>(entries, &self.hash_builder),
207 );
208 true
209 }
210 }
211 }
212
213 pub fn remove(&mut self, entries: &[Entry], index: usize) {
215 let key = &entries[index].key;
216 let hash = self.hash_builder.hash_one(key);
217 if let Some(bucket) = self.table.find(hash, equivalent_key(entries, key)) {
218 let indexes = unsafe { bucket.as_mut() };
219
220 if !indexes.remove(index) {
221 unsafe { self.table.remove(bucket) };
222 }
223 }
224 }
225
226 pub fn shift_down(&mut self, index: usize) {
228 unsafe {
229 for bucket in self.table.iter() {
230 let indexes = bucket.as_mut();
231 indexes.shift_down(index)
232 }
233 }
234 }
235
236 pub fn shift_up(&mut self, index: usize) {
238 unsafe {
239 for bucket in self.table.iter() {
240 let indexes = bucket.as_mut();
241 indexes.shift_up(index)
242 }
243 }
244 }
245
246 pub fn clear(&mut self) {
247 self.table.clear()
248 }
249}
250
251#[cfg(test)]
252mod tests {
253 use super::*;
254 use crate::Value;
255
256 #[test]
257 fn insert() {
258 let entries = [
259 Entry::new("a".into(), Value::Null),
260 Entry::new("b".into(), Value::Null),
261 Entry::new("a".into(), Value::Null),
262 ];
263
264 let mut indexes: IndexMap = IndexMap::default();
265 indexes.insert(&entries, 2);
266 indexes.insert(&entries, 1);
267 indexes.insert(&entries, 0);
268
269 let mut a = indexes.get(&entries, "a").unwrap().iter();
270 let mut b = indexes.get(&entries, "b").unwrap().iter();
271
272 assert_eq!(a.next(), Some(0));
273 assert_eq!(a.next(), Some(2));
274 assert_eq!(a.next(), None);
275 assert_eq!(b.next(), Some(1));
276 assert_eq!(b.next(), None);
277 assert_eq!(indexes.get(&entries, "c"), None)
278 }
279
280 #[test]
281 fn remove1() {
282 let entries = [
283 Entry::new("a".into(), Value::Null),
284 Entry::new("b".into(), Value::Null),
285 Entry::new("a".into(), Value::Null),
286 ];
287
288 let mut indexes: IndexMap = IndexMap::default();
289 indexes.insert(&entries, 2);
290 indexes.insert(&entries, 1);
291 indexes.insert(&entries, 0);
292
293 indexes.remove(&entries, 1);
294 indexes.remove(&entries, 0);
295
296 let mut a = indexes.get(&entries, "a").unwrap().iter();
297
298 assert_eq!(a.next(), Some(2));
299 assert_eq!(a.next(), None);
300 assert_eq!(indexes.get(&entries, "b"), None)
301 }
302
303 #[test]
304 fn remove2() {
305 let entries = [
306 Entry::new("a".into(), Value::Null),
307 Entry::new("b".into(), Value::Null),
308 Entry::new("a".into(), Value::Null),
309 ];
310
311 let mut indexes: IndexMap = IndexMap::default();
312 indexes.insert(&entries, 2);
313 indexes.insert(&entries, 1);
314 indexes.insert(&entries, 0);
315
316 indexes.remove(&entries, 0);
317 indexes.remove(&entries, 1);
318 indexes.remove(&entries, 2);
319
320 assert_eq!(indexes.get(&entries, "a"), None);
321 assert_eq!(indexes.get(&entries, "b"), None)
322 }
323}