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}