broccoli_tree/
node.rs

1use super::*;
2
3/// The underlying number type used for the tree.
4/// It is auto implemented by all types that satisfy the type constraints.
5/// Notice that no arithmetic is possible. The tree is constructed
6/// using only comparisons and copying.
7pub trait Num: PartialOrd + Copy + Default + std::fmt::Debug {}
8impl<T> Num for T where T: PartialOrd + Copy + Default + std::fmt::Debug {}
9
10///
11/// Trait to signify that this object has an axis aligned bounding box.
12///
13pub trait Aabb {
14    type Num: Num;
15    fn get(&self) -> &Rect<Self::Num>;
16}
17
18impl<T: Aabb> Aabb for &T {
19    type Num = T::Num;
20    #[inline(always)]
21    fn get(&self) -> &Rect<Self::Num> {
22        T::get(self)
23    }
24}
25impl<T: Aabb> Aabb for &mut T {
26    type Num = T::Num;
27    #[inline(always)]
28    fn get(&self) -> &Rect<Self::Num> {
29        T::get(self)
30    }
31}
32
33impl<N: Num> Aabb for Rect<N> {
34    type Num = N;
35    #[inline(always)]
36    fn get(&self) -> &Rect<Self::Num> {
37        self
38    }
39}
40
41/// A bounding box container object that implements [`Aabb`] and [`HasInner`].
42/// Note that `&mut BBox<N,T>` also implements [`Aabb`] and [`HasInner`].
43///
44/// Using this one struct the user can construct the following types for bboxes to be inserted into the tree:
45///
46///* `BBox<N,T>`  (direct)
47///* `&mut BBox<N,T>` (indirect)
48///* `BBox<N,&mut T>` (rect direct, T indirect)
49#[derive(Debug, Copy, Clone)]
50pub struct BBox<N, T> {
51    pub rect: Rect<N>,
52    pub inner: T,
53}
54
55impl<N, T> BBox<N, T> {
56    /// Constructor. Also consider using [`crate::bbox()`]
57    #[inline(always)]
58    #[must_use]
59    pub fn new(rect: Rect<N>, inner: T) -> BBox<N, T> {
60        BBox { rect, inner }
61    }
62}
63
64impl<N: Num, T> Aabb for BBox<N, T> {
65    type Num = N;
66    #[inline(always)]
67    fn get(&self) -> &Rect<Self::Num> {
68        &self.rect
69    }
70}
71
72impl<N: Num, T> HasInner for BBox<N, T> {
73    type Inner = T;
74    #[inline(always)]
75    fn destruct_mut(&mut self) -> (&Rect<Self::Num>, &mut Self::Inner) {
76        (&self.rect, &mut self.inner)
77    }
78}
79
80impl<N: Num, T> HasInner for &mut BBox<N, T> {
81    type Inner = T;
82    #[inline(always)]
83    fn destruct_mut(&mut self) -> (&Rect<Self::Num>, &mut Self::Inner) {
84        (&self.rect, &mut self.inner)
85    }
86}
87
88///
89/// BBox with a reference.
90///
91/// Similar to `BBox<N,&mut T>` except
92/// get_inner_mut() doesnt return a `&mut &mut T`
93/// but instead just a `&mut T`.
94///
95pub struct BBoxMut<'a, N, T> {
96    pub rect: axgeom::Rect<N>,
97    pub inner: &'a mut T,
98}
99
100impl<'a, N, T> BBoxMut<'a, N, T> {
101    /// Constructor. Also consider using [`crate::bbox()`]
102    #[inline(always)]
103    #[must_use]
104    pub fn new(rect: Rect<N>, inner: &'a mut T) -> BBoxMut<'a, N, T> {
105        BBoxMut { rect, inner }
106    }
107}
108impl<N: Num, T> Aabb for BBoxMut<'_, N, T> {
109    type Num = N;
110    #[inline(always)]
111    fn get(&self) -> &axgeom::Rect<N> {
112        &self.rect
113    }
114}
115impl<N: Num, T> HasInner for BBoxMut<'_, N, T> {
116    type Inner = T;
117    #[inline(always)]
118    fn destruct_mut(&mut self) -> (&Rect<Self::Num>, &mut Self::Inner) {
119        (&self.rect, self.inner)
120    }
121}
122
123/// When we traverse the tree in read-only mode, we can simply return a reference to each node.
124/// We don't need to protect the user from only mutating parts of the BBox's since they can't
125/// change anything.
126pub type Vistr<'a, N> = compt::dfs_order::Vistr<'a, N, compt::dfs_order::PreOrder>;
127
128mod vistr_mut {
129    use crate::*;
130
131    /// Tree Iterator that returns a protected mutable reference to each node.
132    #[repr(transparent)]
133    #[must_use]
134    pub struct VistrMutPin<'a, N> {
135        inner: compt::dfs_order::VistrMut<'a, N, compt::dfs_order::PreOrder>,
136    }
137
138    impl<'a, N> VistrMutPin<'a, N> {
139        #[inline(always)]
140        pub(crate) fn new(
141            inner: compt::dfs_order::VistrMut<'a, N, compt::dfs_order::PreOrder>,
142        ) -> Self {
143            VistrMutPin { inner }
144        }
145        /// It is safe to borrow the iterator and then produce mutable references from that
146        /// as long as by the time the borrow ends, all the produced references also go away.
147        #[inline(always)]
148        pub fn borrow_mut(&mut self) -> VistrMutPin<N> {
149            VistrMutPin {
150                inner: self.inner.borrow_mut(),
151            }
152        }
153
154        #[inline(always)]
155        pub fn borrow(&self) -> Vistr<N> {
156            self.inner.borrow()
157        }
158
159        #[inline(always)]
160        pub fn get_height(&self) -> usize {
161            compt::FixedDepthVisitor::get_height(self)
162        }
163
164        #[inline(always)]
165        pub fn into_slice(self) -> AabbPin<&'a mut [N]> {
166            AabbPin::new(self.inner.into_slice())
167        }
168    }
169
170    impl<'a, N> compt::FixedDepthVisitor for VistrMutPin<'a, N> {}
171
172    impl<'a, N> Visitor for VistrMutPin<'a, N> {
173        type Item = AabbPin<&'a mut N>;
174
175        #[inline(always)]
176        fn next(self) -> (Self::Item, Option<[Self; 2]>) {
177            let (nn, rest) = self.inner.next();
178
179            let k = rest
180                .map(|[left, right]| [VistrMutPin { inner: left }, VistrMutPin { inner: right }]);
181
182            (AabbPin::new(nn), k)
183        }
184
185        #[inline(always)]
186        fn level_remaining_hint(&self) -> (usize, Option<usize>) {
187            self.inner.level_remaining_hint()
188        }
189
190        #[inline(always)]
191        fn dfs_preorder(self, mut func: impl FnMut(Self::Item)) {
192            self.inner.dfs_preorder(move |a| func(AabbPin::new(a)));
193        }
194    }
195}
196pub use vistr_mut::VistrMutPin;
197
198/// A node in [`Tree`].
199pub struct Node<'a, T: Aabb> {
200    pub range: AabbPin<&'a mut [T]>,
201
202    /// if range is empty, then value is [default,default].
203    /// if range is not empty, then cont is the min max bounds in on the y axis (if the node belongs to the x axis).
204    pub cont: axgeom::Range<T::Num>,
205
206    /// for non leafs:
207    ///   if there is a bot either in this node or in a child node, then div is some.
208    ///
209    /// for leafs:
210    ///   value is none
211    pub div: Option<T::Num>,
212
213    ///
214    /// The minimum number of elements in a child node.
215    /// If the left child has 500 bots, and the right child has 20, then
216    /// this value will be 20.
217    ///
218    /// This is used to determine when to start a parallel task.
219    /// Starting a parallel task has overhead so we only want to split
220    /// one off if we know that both threads have a decent amount of work
221    /// to perform in parallel.
222    ///
223    pub num_elem: usize,
224}
225
226impl<'a, T: Aabb> HasElem for Node<'a, T> {
227    type T = T;
228    fn get_elems(&mut self) -> AabbPin<&mut [T]> {
229        self.range.borrow_mut()
230    }
231}
232pub trait HasElem {
233    type T;
234    fn get_elems(&mut self) -> AabbPin<&mut [Self::T]>;
235}
236
237///
238/// Like [`Node`] except only has the number of elem instead of a slice..
239///
240#[derive(Debug, Clone)]
241pub struct NodeData<N: Num> {
242    pub range: usize,
243    pub cont: axgeom::Range<N>,
244    pub div: Option<N>,
245    pub num_elem: usize,
246}
247
248pub use axgeom::Range;
249pub use axgeom::Rect;