eytzinger_map/lib.rs
1//! This crate implements array map or vec mac using eytzinger search algorithm.
2//! Note that these maps does not support insert/remove operations due to cost.
3
4use eytzinger::SliceExt;
5use std::borrow::Borrow;
6
7pub trait AsSlice {
8 type Key: Ord;
9 type Value;
10
11 fn as_slice<'a>(&'a self) -> &'a [(Self::Key, Self::Value)];
12}
13
14pub trait AsMutSlice: AsSlice {
15 fn as_mut_slice(&mut self) -> &mut [(Self::Key, Self::Value)];
16}
17
18impl<K: Ord, V, const LEN: usize> AsSlice for [(K, V); LEN] {
19 type Key = K;
20 type Value = V;
21
22 fn as_slice(&self) -> &[(Self::Key, Self::Value)] {
23 self
24 }
25}
26
27impl<K: Ord, V, const LEN: usize> AsMutSlice for [(K, V); LEN] {
28 fn as_mut_slice(&mut self) -> &mut [(Self::Key, Self::Value)] {
29 self
30 }
31}
32
33impl<K: Ord, V> AsSlice for &[(K, V)] {
34 type Key = K;
35 type Value = V;
36
37 fn as_slice(&self) -> &[(Self::Key, Self::Value)] {
38 self
39 }
40}
41
42impl<K: Ord, V> AsSlice for &mut [(K, V)] {
43 type Key = K;
44 type Value = V;
45
46 fn as_slice(&self) -> &[(Self::Key, Self::Value)] {
47 self
48 }
49}
50
51impl<K: Ord, V> AsMutSlice for &mut [(K, V)] {
52 fn as_mut_slice(&mut self) -> &mut [(Self::Key, Self::Value)] {
53 self
54 }
55}
56
57impl<K: Ord, V> AsSlice for Vec<(K, V)> {
58 type Key = K;
59 type Value = V;
60
61 fn as_slice(&self) -> &[(Self::Key, Self::Value)] {
62 self
63 }
64}
65
66impl<K: Ord, V> AsMutSlice for Vec<(K, V)> {
67 fn as_mut_slice(&mut self) -> &mut [(Self::Key, Self::Value)] {
68 self
69 }
70}
71
72/// A map based on a generic slice-compatible type with Eytzinger binary search.
73///
74/// # Examples
75///
76/// ```
77/// use eytzinger_map::EytzingerMap;
78///
79/// // `EytzingerMap` doesn't have insert. Build one from another map.
80/// let mut movie_reviews = std::collections::BTreeMap::new();
81///
82/// // review some movies.
83/// movie_reviews.insert("Office Space", "Deals with real issues in the workplace.");
84/// movie_reviews.insert("Pulp Fiction", "Masterpiece.");
85/// movie_reviews.insert("The Godfather", "Very enjoyable.");
86///
87/// let movie_reviews: EytzingerMap<_> = movie_reviews.into_iter().collect();
88///
89/// // check for a specific one.
90/// if !movie_reviews.contains_key("Les Misérables") {
91/// println!("We've got {} reviews, but Les Misérables ain't one.",
92/// movie_reviews.len());
93/// }
94///
95/// // look up the values associated with some keys.
96/// let to_find = ["Up!", "Office Space"];
97/// for movie in &to_find {
98/// match movie_reviews.get(movie) {
99/// Some(review) => println!("{}: {}", movie, review),
100/// None => println!("{} is unreviewed.", movie)
101/// }
102/// }
103///
104/// // Look up the value for a key (will panic if the key is not found).
105/// println!("Movie review: {}", movie_reviews["Office Space"]);
106///
107/// // iterate over everything.
108/// for (movie, review) in movie_reviews.iter() {
109/// println!("{}: \"{}\"", movie, review);
110/// }
111/// ```
112#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
113pub struct EytzingerMap<S>(S);
114
115impl<S, K, V> AsRef<[(K, V)]> for EytzingerMap<S>
116where
117 S: AsRef<[(K, V)]>,
118{
119 fn as_ref(&self) -> &[(K, V)] {
120 self.0.as_ref()
121 }
122}
123
124impl<S, K, V> AsMut<[(K, V)]> for EytzingerMap<S>
125where
126 K: Ord,
127 S: AsMut<[(K, V)]>,
128{
129 fn as_mut(&mut self) -> &mut [(K, V)] {
130 self.0.as_mut()
131 }
132}
133
134impl<Q: ?Sized, S> std::ops::Index<&Q> for EytzingerMap<S>
135where
136 S::Key: Borrow<Q> + Ord,
137 Q: Ord,
138 S: AsSlice,
139{
140 type Output = S::Value;
141
142 /// Returns a reference to the value corresponding to the supplied key.
143 ///
144 /// # Panics
145 ///
146 /// Panics if the key is not present in the `BTreeMap`.
147 #[inline]
148 fn index(&self, key: &Q) -> &S::Value {
149 self.get(key).expect("no entry found for key")
150 }
151}
152
153impl<S, K, V> IntoIterator for EytzingerMap<S>
154where
155 S: std::iter::IntoIterator<Item = (K, V)>,
156{
157 type Item = (K, V);
158 type IntoIter = S::IntoIter;
159
160 fn into_iter(self) -> S::IntoIter {
161 self.0.into_iter()
162 }
163}
164
165impl<K, V> std::iter::FromIterator<(K, V)> for EytzingerMap<Vec<(K, V)>>
166where
167 K: Ord,
168{
169 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
170 let items: Vec<_> = iter.into_iter().collect();
171 Self::new(items)
172 }
173}
174
175impl<S> EytzingerMap<S>
176where
177 S: AsSlice,
178{
179 pub fn new(mut s: S) -> Self
180 where
181 S: AsMutSlice,
182 {
183 s.as_mut_slice().sort_unstable_by(|a, b| a.0.cmp(&b.0));
184 Self::from_sorted(s)
185 }
186
187 pub fn from_sorted(mut s: S) -> Self
188 where
189 S: AsSlice + AsMutSlice,
190 {
191 s.as_mut_slice()
192 .eytzingerize(&mut eytzinger::permutation::InplacePermutator);
193 Self(s)
194 }
195
196 pub fn from_eytzingerized(s: S) -> Self
197 where
198 S: AsSlice,
199 {
200 Self(s)
201 }
202
203 #[inline]
204 fn find<Q: ?Sized>(&self, key: &Q) -> Option<usize>
205 where
206 S::Key: Borrow<Q> + Ord,
207 Q: Ord,
208 {
209 self.0
210 .as_slice()
211 .eytzinger_search_by(|x| x.0.borrow().cmp(key))
212 }
213
214 /// Returns a reference to the value corresponding to the key.
215 ///
216 /// The key may be any borrowed form of the map's key type, but the ordering
217 /// on the borrowed form *must* match the ordering on the key type.
218 ///
219 /// # Examples
220 ///
221 /// Basic usage:
222 ///
223 /// ```
224 /// use eytzinger_map::EytzingerMap;
225 ///
226 /// let map = EytzingerMap::new(vec![(1, "a")]);
227 /// assert_eq!(map.get(&1), Some(&"a"));
228 /// assert_eq!(map.get(&2), None);
229 /// ```
230 pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&S::Value>
231 where
232 S::Key: Borrow<Q> + Ord,
233 Q: Ord,
234 {
235 self.find(key)
236 .map(|i| &unsafe { self.0.as_slice().get_unchecked(i) }.1)
237 }
238
239 /// Returns the key-value pair corresponding to the supplied key.
240 ///
241 /// The supplied key may be any borrowed form of the map's key type, but the ordering
242 /// on the borrowed form *must* match the ordering on the key type.
243 ///
244 /// # Examples
245 ///
246 /// ```
247 /// use eytzinger_map::EytzingerMap;
248 ///
249 /// let map = EytzingerMap::new(vec![(1, "a")]);
250 /// assert_eq!(map.get_key_value(&1), Some(&(1, "a")));
251 /// assert_eq!(map.get_key_value(&2), None);
252 /// ```
253 pub fn get_key_value<Q: ?Sized>(&self, key: &Q) -> Option<&(S::Key, S::Value)>
254 where
255 S::Key: Borrow<Q> + Ord,
256 Q: Ord,
257 {
258 self.find(key)
259 .map(|i| unsafe { self.0.as_slice().get_unchecked(i) })
260 }
261
262 /// Returns `true` if the map contains a value for the specified key.
263 ///
264 /// The key may be any borrowed form of the map's key type, but the ordering
265 /// on the borrowed form *must* match the ordering on the key type.
266 ///
267 /// # Examples
268 ///
269 /// Basic usage:
270 ///
271 /// ```
272 /// use eytzinger_map::EytzingerMap;
273 ///
274 /// let map = EytzingerMap::new(vec![(1, "a")]);
275 /// assert_eq!(map.contains_key(&1), true);
276 /// assert_eq!(map.contains_key(&2), false);
277 /// ```
278 pub fn contains_key<Q>(&self, key: &Q) -> bool
279 where
280 S::Key: Borrow<Q> + Ord,
281 Q: Ord + ?Sized,
282 {
283 self.find(key).is_some()
284 }
285
286 // range, range_mut
287
288 /// Gets an iterator over the entries of the map.
289 ///
290 /// # Examples
291 ///
292 /// Basic usage:
293 ///
294 /// ```
295 /// use eytzinger_map::EytzingerMap;
296 ///
297 /// let map = EytzingerMap::new(vec![(3, "c"), (2, "b"), (1, "a")]);
298 ///
299 /// for (key, val) in map.iter() {
300 /// println!("key: {} val: {}", key, val);
301 /// }
302 /// ```
303 pub fn iter(&self) -> impl std::iter::Iterator<Item = &(S::Key, S::Value)> {
304 self.0.as_slice().iter()
305 }
306
307 /// Gets an iterator over the keys of the map.
308 ///
309 /// # Examples
310 ///
311 /// Basic usage:
312 ///
313 /// ```
314 /// use eytzinger_map::EytzingerMap;
315 ///
316 /// let map = EytzingerMap::new(vec![(2, "b"), (1, "a")]);
317 ///
318 /// for key in map.keys() {
319 /// println!("{}", key);
320 /// }
321 /// ```
322 pub fn keys(&self) -> impl std::iter::Iterator<Item = &S::Key> {
323 self.iter().map(|(k, _v)| k)
324 }
325
326 /// Gets an iterator over the values of the map.
327 ///
328 /// # Examples
329 ///
330 /// Basic usage:
331 ///
332 /// ```
333 /// use eytzinger_map::EytzingerMap;
334 ///
335 /// let map = EytzingerMap::new(vec![(1, "hello"), (2, "goodbye")]);
336 ///
337 /// for val in map.values() {
338 /// println!("{}", val);
339 /// }
340 /// ```
341 pub fn values(&self) -> impl std::iter::Iterator<Item = &S::Value> {
342 self.iter().map(|(_k, v)| v)
343 }
344
345 /// Returns the number of elements in the map.
346 ///
347 /// # Examples
348 ///
349 /// Basic usage:
350 ///
351 /// ```
352 /// use eytzinger_map::EytzingerMap;
353 ///
354 /// let mut a = EytzingerMap::new(vec![]);
355 /// assert_eq!(a.len(), 0);
356 /// a = EytzingerMap::new(vec![(1, "a")]);
357 /// assert_eq!(a.len(), 1);
358 /// ```
359 pub fn len(&self) -> usize {
360 self.0.as_slice().len()
361 }
362
363 /// Returns `true` if the map contains no elements.
364 ///
365 /// # Examples
366 ///
367 /// Basic usage:
368 ///
369 /// ```
370 /// use eytzinger_map::EytzingerMap;
371 ///
372 /// let mut a = EytzingerMap::new(vec![]);
373 /// assert!(a.is_empty());
374 /// a = EytzingerMap::new(vec![(1, "a")]);
375 /// assert!(!a.is_empty());
376 /// ```
377 pub fn is_empty(&self) -> bool {
378 self.0.as_slice().is_empty()
379 }
380}
381
382impl<S> EytzingerMap<S>
383where
384 S: AsMutSlice,
385{
386 /// Returns a mutable reference to the value corresponding to the key.
387 ///
388 /// The key may be any borrowed form of the map's key type, but the ordering
389 /// on the borrowed form *must* match the ordering on the key type.
390 ///
391 /// # Examples
392 ///
393 /// Basic usage:
394 ///
395 /// ```
396 /// use eytzinger_map::EytzingerMap;
397 ///
398 /// let mut map = EytzingerMap::new(vec![(1, "a")]);
399 /// if let Some(x) = map.get_mut(&1) {
400 /// *x = "b";
401 /// }
402 /// assert_eq!(map[&1], "b");
403 /// ```
404 pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut S::Value>
405 where
406 S::Key: Borrow<Q> + Ord,
407 Q: Ord,
408 {
409 let i = self.find(key)?;
410 Some(&mut unsafe { self.0.as_mut_slice().get_unchecked_mut(i) }.1)
411 }
412
413 /// Gets a mutable iterator over the entries of the map.
414 ///
415 /// # Examples
416 ///
417 /// Basic usage:
418 ///
419 /// ```
420 /// use eytzinger_map::EytzingerMap;
421 ///
422 /// let mut map = EytzingerMap::new(vec![("a", 1), ("b", 2), ("c", 3)]);
423 ///
424 /// // Update all values
425 /// for (_, val) in map.iter_mut() {
426 /// *val *= 2;
427 /// }
428 ///
429 /// for (key, val) in map.iter() {
430 /// println!("key: {} val: {}", key, val);
431 /// }
432 /// ```
433 pub fn iter_mut(&mut self) -> impl std::iter::Iterator<Item = &mut (S::Key, S::Value)> {
434 self.0.as_mut_slice().iter_mut()
435 }
436
437 /// Gets a mutable iterator over the values of the map.
438 ///
439 /// # Examples
440 ///
441 /// Basic usage:
442 ///
443 /// ```
444 /// use eytzinger_map::EytzingerMap;
445 ///
446 /// let mut map = EytzingerMap::new(vec![("a", 1), ("b", 2), ("c", 3)]);
447 ///
448 /// for val in map.values_mut() {
449 /// *val = *val + 10;
450 /// }
451 ///
452 /// for val in map.values() {
453 /// println!("{}", val);
454 /// }
455 /// ```
456 pub fn values_mut(&mut self) -> impl std::iter::Iterator<Item = &mut S::Value> {
457 self.iter_mut().map(|(_k, v)| v)
458 }
459}
460
461/// A map based on an array with Eytzinger binary search.
462/// See [EytzingerMap](eytzinger-map::EytzingerMap) for details.
463///
464/// ```
465/// use eytzinger_map::EytzingerArrayMap;
466///
467/// let map = EytzingerArrayMap::new([(1, "a"), (2, "b"), (3, "c")]);
468/// assert_eq!(map[&1], "a");
469/// ```
470pub type EytzingerArrayMap<K, V, const LEN: usize> = EytzingerMap<[(K, V); LEN]>;
471/// A map based on a Vec with Eytzinger binary search.
472/// See [EytzingerMap](eytzinger-map::EytzingerMap) for details.
473///
474/// ```
475/// use eytzinger_map::EytzingerVecMap;
476///
477/// let map = EytzingerVecMap::new(vec![(1, "a"), (2, "b"), (3, "c")]);
478/// assert_eq!(map[&1], "a");
479/// ```
480pub type EytzingerVecMap<K, V> = EytzingerMap<Vec<(K, V)>>;
481/// A map based on a slice ref with Eytzinger binary search.
482/// See [EytzingerMap](eytzinger-map::EytzingerMap) for details.
483///
484/// This is useful when the base data is owned by other data.
485/// ```
486/// use eytzinger_map::EytzingerRefMap;
487///
488/// let mut vec = vec![(1, "a"), (2, "b"), (3, "c")];
489/// let map = EytzingerRefMap::from_ref(vec.as_mut_slice());
490/// assert_eq!(map[&1], "a");
491/// ```
492pub type EytzingerRefMap<'a, K, V> = EytzingerMap<&'a [(K, V)]>;
493
494impl<'a, K, V> EytzingerRefMap<'a, K, V>
495where
496 K: Ord,
497{
498 pub fn from_sorted_ref(s: &'a mut [(K, V)]) -> Self {
499 s.eytzingerize(&mut eytzinger::permutation::InplacePermutator);
500 Self(s)
501 }
502
503 pub fn from_ref(s: &'a mut [(K, V)]) -> Self {
504 s.sort_unstable_by(|a, b| a.0.cmp(&b.0));
505 Self::from_sorted_ref(s)
506 }
507}