Skip to main content

cranelift_bforest/
set.rs

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