dynomite/util/rbtree.rs
1//! Ordered key/value map with a `lower_bound` operation.
2//!
3//! The C engine uses a hand-rolled red-black tree (`dyn_rbtree`)
4//! exclusively for token-ring lookups: callers want the smallest key
5//! greater than or equal to a probe value. The Rust port wraps
6//! [`std::collections::BTreeMap`] which already supports both ordered
7//! iteration and `range` queries efficiently.
8
9use std::collections::BTreeMap;
10
11/// Ordered key/value map backed by [`BTreeMap`].
12///
13/// # Examples
14///
15/// ```
16/// use dynomite::util::rbtree::OrderedMap;
17///
18/// let mut t: OrderedMap<u64, &'static str> = OrderedMap::new();
19/// t.insert(10, "ten");
20/// t.insert(30, "thirty");
21/// t.insert(20, "twenty");
22/// assert_eq!(t.lower_bound(&15), Some((&20, &"twenty")));
23/// assert_eq!(t.min(), Some((&10, &"ten")));
24/// ```
25#[derive(Debug, Default, Clone)]
26pub struct OrderedMap<K: Ord, V> {
27 inner: BTreeMap<K, V>,
28}
29
30impl<K: Ord, V> OrderedMap<K, V> {
31 /// Construct an empty map.
32 ///
33 /// # Examples
34 ///
35 /// ```
36 /// use dynomite::util::rbtree::OrderedMap;
37 /// let m: OrderedMap<u32, u32> = OrderedMap::new();
38 /// assert!(m.is_empty());
39 /// ```
40 pub fn new() -> Self {
41 Self {
42 inner: BTreeMap::new(),
43 }
44 }
45
46 /// Insert `value` at `key`, returning the previous value (if any).
47 ///
48 /// # Examples
49 ///
50 /// ```
51 /// use dynomite::util::rbtree::OrderedMap;
52 /// let mut m: OrderedMap<u32, u32> = OrderedMap::new();
53 /// assert_eq!(m.insert(1, 10), None);
54 /// assert_eq!(m.insert(1, 20), Some(10));
55 /// ```
56 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
57 self.inner.insert(key, value)
58 }
59
60 /// Remove the entry at `key`.
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// use dynomite::util::rbtree::OrderedMap;
66 /// let mut m: OrderedMap<u32, u32> = OrderedMap::new();
67 /// m.insert(1, 10);
68 /// assert_eq!(m.remove(&1), Some(10));
69 /// ```
70 pub fn remove(&mut self, key: &K) -> Option<V> {
71 self.inner.remove(key)
72 }
73
74 /// Look up the value at `key`.
75 ///
76 /// # Examples
77 ///
78 /// ```
79 /// use dynomite::util::rbtree::OrderedMap;
80 /// let mut m: OrderedMap<u32, u32> = OrderedMap::new();
81 /// m.insert(1, 10);
82 /// assert_eq!(m.get(&1), Some(&10));
83 /// ```
84 pub fn get(&self, key: &K) -> Option<&V> {
85 self.inner.get(key)
86 }
87
88 /// Number of entries.
89 ///
90 /// # Examples
91 ///
92 /// ```
93 /// use dynomite::util::rbtree::OrderedMap;
94 /// let mut m: OrderedMap<u32, u32> = OrderedMap::new();
95 /// m.insert(1, 1);
96 /// assert_eq!(m.len(), 1);
97 /// ```
98 pub fn len(&self) -> usize {
99 self.inner.len()
100 }
101
102 /// Whether the map is empty.
103 ///
104 /// # Examples
105 ///
106 /// ```
107 /// use dynomite::util::rbtree::OrderedMap;
108 /// let m: OrderedMap<u32, u32> = OrderedMap::new();
109 /// assert!(m.is_empty());
110 /// ```
111 pub fn is_empty(&self) -> bool {
112 self.inner.is_empty()
113 }
114
115 /// Drop every entry.
116 ///
117 /// # Examples
118 ///
119 /// ```
120 /// use dynomite::util::rbtree::OrderedMap;
121 /// let mut m: OrderedMap<u32, u32> = OrderedMap::new();
122 /// m.insert(1, 1);
123 /// m.clear();
124 /// assert!(m.is_empty());
125 /// ```
126 pub fn clear(&mut self) {
127 self.inner.clear();
128 }
129
130 /// Smallest entry, or [`None`] if the map is empty.
131 ///
132 /// # Examples
133 ///
134 /// ```
135 /// use dynomite::util::rbtree::OrderedMap;
136 /// let mut m: OrderedMap<u32, u32> = OrderedMap::new();
137 /// m.insert(3, 30);
138 /// m.insert(1, 10);
139 /// assert_eq!(m.min(), Some((&1, &10)));
140 /// ```
141 pub fn min(&self) -> Option<(&K, &V)> {
142 self.inner.iter().next()
143 }
144
145 /// Largest entry, or [`None`] if the map is empty.
146 ///
147 /// # Examples
148 ///
149 /// ```
150 /// use dynomite::util::rbtree::OrderedMap;
151 /// let mut m: OrderedMap<u32, u32> = OrderedMap::new();
152 /// m.insert(3, 30);
153 /// m.insert(1, 10);
154 /// assert_eq!(m.max(), Some((&3, &30)));
155 /// ```
156 pub fn max(&self) -> Option<(&K, &V)> {
157 self.inner.iter().next_back()
158 }
159
160 /// Smallest entry whose key is `>= probe`. Used by the token ring
161 /// for "find the owner of this key" queries.
162 ///
163 /// # Examples
164 ///
165 /// ```
166 /// use dynomite::util::rbtree::OrderedMap;
167 /// let mut t: OrderedMap<u64, &str> = OrderedMap::new();
168 /// t.insert(10, "a");
169 /// t.insert(20, "b");
170 /// assert_eq!(t.lower_bound(&15), Some((&20, &"b")));
171 /// assert_eq!(t.lower_bound(&25), None);
172 /// assert_eq!(t.lower_bound(&20), Some((&20, &"b")));
173 /// ```
174 pub fn lower_bound(&self, probe: &K) -> Option<(&K, &V)> {
175 self.inner.range(probe..).next()
176 }
177
178 /// In-order iterator over the entries.
179 ///
180 /// # Examples
181 ///
182 /// ```
183 /// use dynomite::util::rbtree::OrderedMap;
184 /// let mut m: OrderedMap<u32, u32> = OrderedMap::new();
185 /// m.insert(2, 0);
186 /// m.insert(1, 0);
187 /// let keys: Vec<u32> = m.iter().map(|(k, _)| *k).collect();
188 /// assert_eq!(keys, vec![1, 2]);
189 /// ```
190 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
191 self.inner.iter()
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198
199 #[test]
200 fn ordered_iteration() {
201 let mut t: OrderedMap<u32, u32> = OrderedMap::new();
202 for k in [3, 1, 5, 2, 4] {
203 t.insert(k, k * 10);
204 }
205 let keys: Vec<u32> = t.iter().map(|(k, _)| *k).collect();
206 assert_eq!(keys, vec![1, 2, 3, 4, 5]);
207 }
208
209 #[test]
210 fn min_and_max() {
211 let mut t: OrderedMap<u32, u32> = OrderedMap::new();
212 assert!(t.min().is_none());
213 t.insert(7, 0);
214 t.insert(3, 0);
215 t.insert(11, 0);
216 assert_eq!(t.min().map(|(k, _)| *k), Some(3));
217 assert_eq!(t.max().map(|(k, _)| *k), Some(11));
218 }
219
220 #[test]
221 fn lower_bound_wraps_at_end() {
222 let mut t: OrderedMap<u32, u32> = OrderedMap::new();
223 t.insert(10, 1);
224 t.insert(20, 2);
225 t.insert(30, 3);
226 assert_eq!(t.lower_bound(&0).map(|(k, _)| *k), Some(10));
227 assert_eq!(t.lower_bound(&15).map(|(k, _)| *k), Some(20));
228 assert_eq!(t.lower_bound(&30).map(|(k, _)| *k), Some(30));
229 assert!(t.lower_bound(&31).is_none());
230 }
231}