cranelift_bforest/
set.rs

1//! Forest of sets.
2
3use super::{Comparator, Forest, Node, NodeData, NodePool, Path, SetValue, INNER_SIZE};
4use crate::packed_option::PackedOption;
5#[cfg(test)]
6use alloc::string::String;
7#[cfg(test)]
8use core::fmt;
9use core::marker::PhantomData;
10
11/// Tag type defining forest types for a set.
12struct SetTypes<K>(PhantomData<K>);
13
14impl<K> Forest for SetTypes<K>
15where
16    K: Copy,
17{
18    type Key = K;
19    type Value = SetValue;
20    type LeafKeys = [K; 2 * INNER_SIZE - 1];
21    type LeafValues = [SetValue; 2 * INNER_SIZE - 1];
22
23    fn splat_key(key: Self::Key) -> Self::LeafKeys {
24        [key; 2 * INNER_SIZE - 1]
25    }
26
27    fn splat_value(value: Self::Value) -> Self::LeafValues {
28        [value; 2 * INNER_SIZE - 1]
29    }
30}
31
32/// Memory pool for a forest of `Set` instances.
33pub struct SetForest<K>
34where
35    K: Copy,
36{
37    nodes: NodePool<SetTypes<K>>,
38}
39
40impl<K> SetForest<K>
41where
42    K: Copy,
43{
44    /// Create a new empty forest.
45    pub fn new() -> Self {
46        Self {
47            nodes: NodePool::new(),
48        }
49    }
50
51    /// Clear all sets in the forest.
52    ///
53    /// All `Set` instances belong to this forest are invalidated and should no longer be used.
54    pub fn clear(&mut self) {
55        self.nodes.clear();
56    }
57}
58
59/// B-tree representing an ordered set of `K`s using `C` for comparing elements.
60///
61/// This is not a general-purpose replacement for `BTreeSet`. See the [module
62/// documentation](index.html) for more information about design tradeoffs.
63///
64/// Sets can be cloned, but that operation should only be used as part of cloning the whole forest
65/// they belong to. *Cloning a set does not allocate new memory for the clone*. It creates an alias
66/// of the same memory.
67#[derive(Clone)]
68pub struct Set<K>
69where
70    K: Copy,
71{
72    root: PackedOption<Node>,
73    unused: PhantomData<K>,
74}
75
76impl<K> Set<K>
77where
78    K: Copy,
79{
80    /// Make an empty set.
81    pub fn new() -> Self {
82        Self {
83            root: None.into(),
84            unused: PhantomData,
85        }
86    }
87
88    /// Is this an empty set?
89    pub fn is_empty(&self) -> bool {
90        self.root.is_none()
91    }
92
93    /// Does the set contain `key`?.
94    pub fn contains<C: Comparator<K>>(&self, key: K, forest: &SetForest<K>, comp: &C) -> bool {
95        self.root
96            .expand()
97            .and_then(|root| Path::default().find(key, root, &forest.nodes, comp))
98            .is_some()
99    }
100
101    /// Try to insert `key` into the set.
102    ///
103    /// If the set did not contain `key`, insert it and return true.
104    ///
105    /// If `key` is already present, don't change the set and return false.
106    pub fn insert<C: Comparator<K>>(
107        &mut self,
108        key: K,
109        forest: &mut SetForest<K>,
110        comp: &C,
111    ) -> bool {
112        self.cursor(forest, comp).insert(key)
113    }
114
115    /// Remove `key` from the set and return true.
116    ///
117    /// If `key` was not present in the set, return false.
118    pub fn remove<C: Comparator<K>>(
119        &mut self,
120        key: K,
121        forest: &mut SetForest<K>,
122        comp: &C,
123    ) -> bool {
124        let mut c = self.cursor(forest, comp);
125        if c.goto(key) {
126            c.remove();
127            true
128        } else {
129            false
130        }
131    }
132
133    /// Remove all entries.
134    pub fn clear(&mut self, forest: &mut SetForest<K>) {
135        if let Some(root) = self.root.take() {
136            forest.nodes.free_tree(root);
137        }
138    }
139
140    /// Retains only the elements specified by the predicate.
141    ///
142    /// Remove all elements where the predicate returns false.
143    pub fn retain<F>(&mut self, forest: &mut SetForest<K>, mut predicate: F)
144    where
145        F: FnMut(K) -> bool,
146    {
147        let mut path = Path::default();
148        if let Some(root) = self.root.expand() {
149            path.first(root, &forest.nodes);
150        }
151        while let Some((node, entry)) = path.leaf_pos() {
152            if predicate(forest.nodes[node].unwrap_leaf().0[entry]) {
153                path.next(&forest.nodes);
154            } else {
155                self.root = path.remove(&mut forest.nodes).into();
156            }
157        }
158    }
159
160    /// Create a cursor for navigating this set. The cursor is initially positioned off the end of
161    /// the set.
162    pub fn cursor<'a, C: Comparator<K>>(
163        &'a mut self,
164        forest: &'a mut SetForest<K>,
165        comp: &'a C,
166    ) -> SetCursor<'a, K, C> {
167        SetCursor::new(self, forest, comp)
168    }
169
170    /// Create an iterator traversing this set. The iterator type is `K`.
171    pub fn iter<'a>(&'a self, forest: &'a SetForest<K>) -> SetIter<'a, K> {
172        SetIter {
173            root: self.root,
174            pool: &forest.nodes,
175            path: Path::default(),
176        }
177    }
178}
179
180impl<K> Default for Set<K>
181where
182    K: Copy,
183{
184    fn default() -> Self {
185        Self::new()
186    }
187}
188
189/// A position in a `Set` used to navigate and modify the ordered set.
190///
191/// A cursor always points at an element in the set, or "off the end" which is a position after the
192/// last element in the set.
193pub struct SetCursor<'a, K, C>
194where
195    K: 'a + Copy,
196    C: 'a + Comparator<K>,
197{
198    root: &'a mut PackedOption<Node>,
199    pool: &'a mut NodePool<SetTypes<K>>,
200    comp: &'a C,
201    path: Path<SetTypes<K>>,
202}
203
204impl<'a, K, C> SetCursor<'a, K, C>
205where
206    K: Copy,
207    C: Comparator<K>,
208{
209    /// Create a cursor with a default (invalid) location.
210    fn new(container: &'a mut Set<K>, forest: &'a mut SetForest<K>, comp: &'a C) -> Self {
211        Self {
212            root: &mut container.root,
213            pool: &mut forest.nodes,
214            comp,
215            path: Path::default(),
216        }
217    }
218
219    /// Is this cursor pointing to an empty set?
220    pub fn is_empty(&self) -> bool {
221        self.root.is_none()
222    }
223
224    /// Move cursor to the next element and return it.
225    ///
226    /// If the cursor reaches the end, return `None` and leave the cursor at the off-the-end
227    /// position.
228    pub fn next(&mut self) -> Option<K> {
229        self.path.next(self.pool).map(|(k, _)| k)
230    }
231
232    /// Move cursor to the previous element and return it.
233    ///
234    /// If the cursor is already pointing at the first element, leave it there and return `None`.
235    pub fn prev(&mut self) -> Option<K> {
236        self.root
237            .expand()
238            .and_then(|root| self.path.prev(root, self.pool).map(|(k, _)| k))
239    }
240
241    /// Get the current element, or `None` if the cursor is at the end.
242    pub fn elem(&self) -> Option<K> {
243        self.path
244            .leaf_pos()
245            .and_then(|(node, entry)| self.pool[node].unwrap_leaf().0.get(entry).cloned())
246    }
247
248    /// Move this cursor to `elem`.
249    ///
250    /// If `elem` is in the set, place the cursor at `elem` and return true.
251    ///
252    /// If `elem` is not in the set, place the cursor at the next larger element (or the end) and
253    /// return false.
254    pub fn goto(&mut self, elem: K) -> bool {
255        match self.root.expand() {
256            None => false,
257            Some(root) => {
258                if self.path.find(elem, root, self.pool, self.comp).is_some() {
259                    true
260                } else {
261                    self.path.normalize(self.pool);
262                    false
263                }
264            }
265        }
266    }
267
268    /// Move this cursor to the first element.
269    pub fn goto_first(&mut self) -> Option<K> {
270        self.root.map(|root| self.path.first(root, self.pool).0)
271    }
272
273    /// Try to insert `elem` into the set and leave the cursor at the inserted element.
274    ///
275    /// If the set did not contain `elem`, insert it and return true.
276    ///
277    /// If `elem` is already present, don't change the set, place the cursor at `goto(elem)`, and
278    /// return false.
279    pub fn insert(&mut self, elem: K) -> bool {
280        match self.root.expand() {
281            None => {
282                let root = self.pool.alloc_node(NodeData::leaf(elem, SetValue()));
283                *self.root = root.into();
284                self.path.set_root_node(root);
285                true
286            }
287            Some(root) => {
288                // TODO: Optimize the case where `self.path` is already at the correct insert pos.
289                if self.path.find(elem, root, self.pool, self.comp).is_none() {
290                    *self.root = self.path.insert(elem, SetValue(), self.pool).into();
291                    true
292                } else {
293                    false
294                }
295            }
296        }
297    }
298
299    /// Remove the current element (if any) and return it.
300    /// This advances the cursor to the next element after the removed one.
301    pub fn remove(&mut self) -> Option<K> {
302        let elem = self.elem();
303        if elem.is_some() {
304            *self.root = self.path.remove(self.pool).into();
305        }
306        elem
307    }
308}
309
310#[cfg(test)]
311impl<'a, K, C> SetCursor<'a, K, C>
312where
313    K: Copy + fmt::Display,
314    C: Comparator<K>,
315{
316    fn verify(&self) {
317        self.path.verify(self.pool);
318        self.root.map(|root| self.pool.verify_tree(root, self.comp));
319    }
320
321    /// Get a text version of the path to the current position.
322    fn tpath(&self) -> String {
323        use alloc::string::ToString;
324        self.path.to_string()
325    }
326}
327
328/// An iterator visiting the elements of a `Set`.
329pub struct SetIter<'a, K>
330where
331    K: 'a + Copy,
332{
333    root: PackedOption<Node>,
334    pool: &'a NodePool<SetTypes<K>>,
335    path: Path<SetTypes<K>>,
336}
337
338impl<'a, K> Iterator for SetIter<'a, K>
339where
340    K: 'a + Copy,
341{
342    type Item = K;
343
344    fn next(&mut self) -> Option<Self::Item> {
345        // We use `self.root` to indicate if we need to go to the first element. Reset to `None`
346        // once we've returned the first element. This also works for an empty tree since the
347        // `path.next()` call returns `None` when the path is empty. This also fuses the iterator.
348        match self.root.take() {
349            Some(root) => Some(self.path.first(root, self.pool).0),
350            None => self.path.next(self.pool).map(|(k, _)| k),
351        }
352    }
353}
354
355#[cfg(test)]
356mod tests {
357    use super::*;
358    use alloc::vec::Vec;
359    use core::mem;
360
361    #[test]
362    fn node_size() {
363        // check that nodes are cache line sized when keys are 32 bits.
364        type F = SetTypes<u32>;
365        assert_eq!(mem::size_of::<NodeData<F>>(), 64);
366    }
367
368    #[test]
369    fn empty() {
370        let mut f = SetForest::<u32>::new();
371        f.clear();
372
373        let mut s = Set::<u32>::new();
374        assert!(s.is_empty());
375        s.clear(&mut f);
376        assert!(!s.contains(7, &f, &()));
377
378        // Iterator for an empty set.
379        assert_eq!(s.iter(&f).next(), None);
380
381        s.retain(&mut f, |_| unreachable!());
382
383        let mut c = SetCursor::new(&mut s, &mut f, &());
384        c.verify();
385        assert_eq!(c.elem(), None);
386
387        assert_eq!(c.goto_first(), None);
388        assert_eq!(c.tpath(), "<empty path>");
389    }
390
391    #[test]
392    fn simple_cursor() {
393        let mut f = SetForest::<u32>::new();
394        let mut s = Set::<u32>::new();
395        let mut c = SetCursor::new(&mut s, &mut f, &());
396
397        assert!(c.insert(50));
398        c.verify();
399        assert_eq!(c.elem(), Some(50));
400
401        assert!(c.insert(100));
402        c.verify();
403        assert_eq!(c.elem(), Some(100));
404
405        assert!(c.insert(10));
406        c.verify();
407        assert_eq!(c.elem(), Some(10));
408
409        // Basic movement.
410        assert_eq!(c.next(), Some(50));
411        assert_eq!(c.next(), Some(100));
412        assert_eq!(c.next(), None);
413        assert_eq!(c.next(), None);
414        assert_eq!(c.prev(), Some(100));
415        assert_eq!(c.prev(), Some(50));
416        assert_eq!(c.prev(), Some(10));
417        assert_eq!(c.prev(), None);
418        assert_eq!(c.prev(), None);
419
420        assert!(c.goto(50));
421        assert_eq!(c.elem(), Some(50));
422        assert_eq!(c.remove(), Some(50));
423        c.verify();
424
425        assert_eq!(c.elem(), Some(100));
426        assert_eq!(c.remove(), Some(100));
427        c.verify();
428        assert_eq!(c.elem(), None);
429        assert_eq!(c.remove(), None);
430        c.verify();
431    }
432
433    #[test]
434    fn two_level_sparse_tree() {
435        let mut f = SetForest::<u32>::new();
436        let mut s = Set::<u32>::new();
437        let mut c = SetCursor::new(&mut s, &mut f, &());
438
439        // Insert enough elements that we get a two-level tree.
440        // Each leaf node holds 8 elements
441        assert!(c.is_empty());
442        for i in 0..50 {
443            assert!(c.insert(i));
444            assert_eq!(c.elem(), Some(i));
445        }
446        assert!(!c.is_empty());
447
448        assert_eq!(c.goto_first(), Some(0));
449        assert_eq!(c.tpath(), "node2[0]--node0[0]");
450
451        assert_eq!(c.prev(), None);
452        for i in 1..50 {
453            assert_eq!(c.next(), Some(i));
454        }
455        assert_eq!(c.next(), None);
456        for i in (0..50).rev() {
457            assert_eq!(c.prev(), Some(i));
458        }
459        assert_eq!(c.prev(), None);
460
461        assert!(c.goto(25));
462        for i in 25..50 {
463            assert_eq!(c.remove(), Some(i));
464            assert!(!c.is_empty());
465            c.verify();
466        }
467
468        for i in (0..25).rev() {
469            assert!(!c.is_empty());
470            assert_eq!(c.elem(), None);
471            assert_eq!(c.prev(), Some(i));
472            assert_eq!(c.remove(), Some(i));
473            c.verify();
474        }
475        assert_eq!(c.elem(), None);
476        assert!(c.is_empty());
477    }
478
479    #[test]
480    fn three_level_sparse_tree() {
481        let mut f = SetForest::<u32>::new();
482        let mut s = Set::<u32>::new();
483        let mut c = SetCursor::new(&mut s, &mut f, &());
484
485        // Insert enough elements that we get a 3-level tree.
486        // Each leaf node holds 8 elements when filled up sequentially.
487        // Inner nodes hold 8 node pointers.
488        assert!(c.is_empty());
489        for i in 0..150 {
490            assert!(c.insert(i));
491            assert_eq!(c.elem(), Some(i));
492        }
493        assert!(!c.is_empty());
494
495        assert!(c.goto(0));
496        assert_eq!(c.tpath(), "node11[0]--node2[0]--node0[0]");
497
498        assert_eq!(c.prev(), None);
499        for i in 1..150 {
500            assert_eq!(c.next(), Some(i));
501        }
502        assert_eq!(c.next(), None);
503        for i in (0..150).rev() {
504            assert_eq!(c.prev(), Some(i));
505        }
506        assert_eq!(c.prev(), None);
507
508        assert!(c.goto(125));
509        for i in 125..150 {
510            assert_eq!(c.remove(), Some(i));
511            assert!(!c.is_empty());
512            c.verify();
513        }
514
515        for i in (0..125).rev() {
516            assert!(!c.is_empty());
517            assert_eq!(c.elem(), None);
518            assert_eq!(c.prev(), Some(i));
519            assert_eq!(c.remove(), Some(i));
520            c.verify();
521        }
522        assert_eq!(c.elem(), None);
523        assert!(c.is_empty());
524    }
525
526    // Generate a densely populated 4-level tree.
527    //
528    // Level 1: 1 root
529    // Level 2: 8 inner
530    // Level 3: 64 inner
531    // Level 4: 512 leafs, up to 7680 elements
532    //
533    // A 3-level tree can hold at most 960 elements.
534    fn dense4l(f: &mut SetForest<i32>) -> Set<i32> {
535        f.clear();
536        let mut s = Set::new();
537
538        // Insert 400 elements in 7 passes over the range to avoid the half-full leaf node pattern
539        // that comes from sequential insertion. This will generate a normal leaf layer.
540        for n in 0..4000 {
541            assert!(s.insert((n * 7) % 4000, f, &()));
542        }
543        s
544    }
545
546    #[test]
547    fn four_level() {
548        let mut f = SetForest::<i32>::new();
549        let mut s = dense4l(&mut f);
550
551        assert_eq!(
552            s.iter(&f).collect::<Vec<_>>()[0..10],
553            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
554        );
555
556        let mut c = s.cursor(&mut f, &());
557
558        c.verify();
559
560        // Peel off a whole sub-tree of the root by deleting from the front.
561        // The 900 element is near the front of the second sub-tree.
562        assert!(c.goto(900));
563        assert_eq!(c.tpath(), "node48[1]--node47[0]--node26[0]--node20[4]");
564        assert!(c.goto(0));
565        for i in 0..900 {
566            assert!(!c.is_empty());
567            assert_eq!(c.remove(), Some(i));
568        }
569        c.verify();
570        assert_eq!(c.elem(), Some(900));
571
572        // Delete backwards from somewhere in the middle.
573        assert!(c.goto(3000));
574        for i in (2000..3000).rev() {
575            assert_eq!(c.prev(), Some(i));
576            assert_eq!(c.remove(), Some(i));
577            assert_eq!(c.elem(), Some(3000));
578        }
579        c.verify();
580
581        // Remove everything in a scattered manner, triggering many collapsing patterns.
582        for i in 0..4000 {
583            if c.goto((i * 7) % 4000) {
584                c.remove();
585            }
586        }
587        assert!(c.is_empty());
588    }
589
590    #[test]
591    fn four_level_clear() {
592        let mut f = SetForest::<i32>::new();
593        let mut s = dense4l(&mut f);
594        s.clear(&mut f);
595    }
596}