1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
macro_rules! map { ($treeimport:path) => { use $treeimport::{Tree, Iter}; use std::{fmt::Debug, borrow::Borrow, ops::Bound}; /// This Map uses a similar strategy to BTreeMap to ensure cache /// efficient performance on modern hardware while still providing /// log(N) get, insert, and remove operations. /// # Examples /// ``` /// use std::string::String; /// use self::immutable_chunkmap::rc::map::Map; /// /// let m = /// Map::new() /// .insert(&String::from("1"), &1) /// .insert(&String::from("2"), &2) /// .insert(&String::from("3"), &3); /// /// assert_eq!(m.get("1"), Option::Some(&1)); /// assert_eq!(m.get("2"), Option::Some(&2)); /// assert_eq!(m.get("3"), Option::Some(&3)); /// assert_eq!(m.get("4"), Option::None); /// /// for (k, v) in &m { /// println!("key {}, val: {}", k, v) /// } /// ``` #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Map<K: Ord + Clone + Debug, V: Clone + Debug> { len: usize, root: Tree<K, V> } impl<'a, K, V> IntoIterator for &'a Map<K, V> where K: 'a + Borrow<K> + Ord + Clone + Debug, V: 'a + Clone + Debug { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, K, V>; fn into_iter(self) -> Self::IntoIter { self.root.into_iter() } } impl<K, V> Map<K, V> where K: Ord + Clone + Debug, V: Clone + Debug { /// Create a new empty map pub fn new() -> Self { Map { len: 0, root: Tree::new() } } /// This method inserts many elements at once, skipping /// the intermediate node allocations where possible, /// which in most cases provides a significant speedup. It /// is able to skip more allocations if the data is /// sorted, however it will still work with unsorted data. /// /// #Examples ///``` /// use self::immutable_chunkmap::rc::map::Map; /// /// let mut v = vec![(1, 3), (10, 1), (-12, 2), (44, 0), (50, -1)]; /// v.sort_unstable_by_key(|&(k, _)| k); /// /// let m = Map::new().insert_sorted(v.iter().map(|(k, v)| (*k, *v))); /// /// for (k, v) in &v { /// assert_eq!(m.get(k), Option::Some(v)) /// } /// ``` pub fn insert_sorted<E: IntoIterator<Item=(K, V)>>( &self, elts: E ) -> Self { let (t, len) = self.root.insert_sorted(self.len, elts); Map { len: len, root: t } } /// return a new map with (k, v) inserted into it. If k already /// exists in the old map, the new map will contain the new /// binding, not the old. This method runs in log(N) time, where /// N is the size of the map. `k` and `v` will be cloned on /// insert, and on subsuquent inserts or removals, if `k` or `v` /// is expensive to clone, pass an `Rc` or `Arc` pointer to it /// instead. A `Box` won't work, because it can't be shared, so /// clone will deep copy the contents. pub fn insert(&self, k: &K, v: &V) -> Self { let (t, len) = self.root.insert(self.len, k, v); Map { len: len, root: t } } /// lookup the mapping for k. If it doesn't exist return /// None. Runs in log(N) time where N is the size of the /// map. pub fn get<'a, Q: ?Sized + Ord + Debug>(&'a self, k: &Q) -> Option<&'a V> where K: Borrow<Q> { self.root.get(k) } /// return a new map with the mapping under k /// removed. Runs in log(N) time, where N is the size of /// the map pub fn remove<Q: Sized + Ord>(&self, k: &Q) -> Self where K: Borrow<Q> { let (t, len) = self.root.remove(self.len, k); Map {root: t, len: len} } /// get the number of elements in the map O(1) pub fn len(&self) -> usize { self.len } /// return an iterator over the subset of elements in the /// map that are within the specified range. /// /// The returned iterator runs in O(log(N) + M) time, and /// constant space. N is the number of elements in the /// tree, and M is the number of elements you examine. /// /// if lbound >= ubound the returned iterator will be empty pub fn range<'a, Q>( &'a self, lbound: Bound<Q>, ubound: Bound<Q> ) -> Iter<'a, Q, K, V> where Q: Ord, K: Borrow<Q> { self.root.range(lbound, ubound) } #[allow(dead_code)] pub(crate) fn invariant(&self) -> () { self.root.invariant(self.len) } } }; }