broccoli_tree/
lib.rs

1//!
2//! This is a supporting crate to the  `broccoli` crate. This crate only
3//! provides the broccoli tree and tree building code, but no querying code.
4//!
5
6pub mod aabb_pin;
7mod assert;
8pub mod build;
9pub mod node;
10mod oned;
11pub mod splitter;
12pub mod util;
13
14pub use axgeom;
15
16use aabb_pin::*;
17use axgeom::*;
18use build::*;
19use compt::Visitor;
20use node::*;
21
22///The default starting axis of a [`Tree`]. It is set to be the `X` axis.
23///This means that the first divider is a 'vertical' line since it is
24///partitioning space based off of the aabb's `X` value.
25pub type DefaultA = XAXIS;
26
27///Returns the default axis type.
28#[must_use]
29pub const fn default_axis() -> DefaultA {
30    XAXIS
31}
32
33///Expose a common Sorter trait so that we may have two version of the tree
34///where one implementation actually does sort the tree, while the other one
35///does nothing when sort() is called.
36pub trait Sorter<T: Aabb>: Copy + Clone + Send + Sync {
37    fn sort(&self, axis: impl Axis, bots: &mut [T]);
38}
39
40///Using this struct the user can determine the height of a tree or the number of nodes
41///that would exist if the tree were constructed with the specified number of elements.
42pub mod num_level {
43    pub const fn num_nodes(num_levels: usize) -> usize {
44        2usize.rotate_left(num_levels as u32) - 1
45    }
46
47    ///The default number of elements per node
48    ///
49    ///If we had a node per bot, the tree would have too many levels. Too much time would be spent recursing.
50    ///If we had too many bots per node, you would lose the properties of a tree, and end up with plain sweep and prune.
51    ///Theory would tell you to just make a node per bot, but there is
52    ///a sweet spot inbetween determined by the real-word properties of your computer.
53    ///we want each node to have space for around num_per_node bots.
54    ///there are 2^h nodes.
55    ///2^h*200>=num_bots.  Solve for h s.t. h is an integer.
56    ///Make this number too small, and the tree will have too many levels,
57    ///and too much time will be spent recursing.
58    ///Make this number too high, and you will lose the properties of a tree,
59    ///and you will end up with just sweep and prune.
60    ///This number was chosen empirically from running the Tree_alg_data project,
61    ///on two different machines.
62    pub const DEFAULT_NUMBER_ELEM_PER_NODE: usize = 32;
63
64    ///Outputs the height given an desirned number of bots per node.
65    #[inline]
66    #[must_use]
67    fn compute_tree_height_heuristic(num_bots: usize, num_per_node: usize) -> usize {
68        //we want each node to have space for around 300 bots.
69        //there are 2^h nodes.
70        //2^h*200>=num_bots.  Solve for h s.t. h is an integer.
71
72        if num_bots <= num_per_node {
73            1
74        } else {
75            let (num_bots, num_per_node) = (num_bots as u64, num_per_node as u64);
76            let a = num_bots / num_per_node;
77            let a = log_2(a);
78            let k = (((a / 2) * 2) + 1) as usize;
79            assert_eq!(k % 2, 1, "k={:?}", k);
80            k
81        }
82    }
83    #[must_use]
84    const fn log_2(x: u64) -> u64 {
85        const fn num_bits<T>() -> usize {
86            core::mem::size_of::<T>() * 8
87        }
88        num_bits::<u64>() as u64 - x.leading_zeros() as u64 - 1
89    }
90    #[must_use]
91    pub fn default(num_elements: usize) -> usize {
92        compute_tree_height_heuristic(num_elements, DEFAULT_NUMBER_ELEM_PER_NODE)
93    }
94    ///Specify a custom default number of elements per leaf
95    #[must_use]
96    pub fn with_num_elem_in_leaf(num_elements: usize, num_elem_leaf: usize) -> usize {
97        compute_tree_height_heuristic(num_elements, num_elem_leaf)
98    }
99}
100
101pub use axgeom::rect;
102
103///Shorthand constructor of [`BBox`]
104#[inline(always)]
105#[must_use]
106pub fn bbox<N, T>(rect: axgeom::Rect<N>, inner: T) -> BBox<N, T> {
107    BBox::new(rect, inner)
108}
109
110///Shorthand constructor of [`BBoxMut`]
111#[inline(always)]
112#[must_use]
113pub fn bbox_mut<N, T>(rect: axgeom::Rect<N>, inner: &mut T) -> BBoxMut<N, T> {
114    BBoxMut::new(rect, inner)
115}
116
117///Create a [`Tree`].
118///
119/// # Examples
120///
121///```
122/// let mut bots = [axgeom::rect(0,10,0,10)];
123/// let tree = broccoli_tree::new(&mut bots);
124///
125///```
126pub fn new<T: Aabb>(bots: &mut [T]) -> Tree<T> {
127    TreeBuilder::new(DefaultSorter, bots).build()
128}
129
130#[cfg(feature = "rayon")]
131pub fn new_par<T: Aabb>(bots: &mut [T]) -> Tree<T>
132where
133    T: Send + Sync,
134    T::Num: Send + Sync,
135{
136    TreeBuilder::new(DefaultSorter, bots).build_par()
137}
138
139///
140/// Create a [`TreeOwned`]
141///
142pub fn new_owned<C: Container>(cont: C) -> TreeOwned<C, DefaultSorter>
143where
144    C::T: Aabb,
145{
146    TreeOwned::new(DefaultSorter, cont)
147}
148
149#[cfg(feature = "rayon")]
150pub fn new_owned_par<C: Container>(cont: C) -> TreeOwned<C, DefaultSorter>
151where
152    C::T: Aabb + Send + Sync,
153    <C::T as Aabb>::Num: Send + Sync,
154{
155    TreeOwned::new_par(DefaultSorter, cont)
156}
157
158///
159/// Abstract over containers that produce `&mut [T]`
160///
161pub trait Container {
162    type T;
163    fn as_mut(&mut self) -> &mut [Self::T];
164}
165
166impl<T, const N: usize> Container for [T; N] {
167    type T = T;
168    fn as_mut(&mut self) -> &mut [T] {
169        self
170    }
171}
172impl<T> Container for Vec<T> {
173    type T = T;
174    fn as_mut(&mut self) -> &mut [Self::T] {
175        self
176    }
177}
178impl<T> Container for Box<[T]> {
179    type T = T;
180    fn as_mut(&mut self) -> &mut [Self::T] {
181        self
182    }
183}
184
185///
186/// Owned version of [`Tree`]
187///
188#[must_use]
189pub struct TreeOwned<C: Container, S>
190where
191    C::T: Aabb,
192{
193    inner: C,
194    nodes: TreeInner<NodeData<<C::T as Aabb>::Num>, S>,
195    length: usize,
196}
197
198impl<C: Container, S: Sorter<C::T>> TreeOwned<C, S>
199where
200    C::T: Aabb,
201{
202    pub fn new(sorter: S, mut bots: C) -> TreeOwned<C, S> {
203        let j = bots.as_mut();
204        let length = j.len();
205
206        let t = TreeBuilder::new(sorter, j).build();
207        let data = t.into_node_data_tree();
208        TreeOwned {
209            inner: bots,
210            nodes: data,
211            length,
212        }
213    }
214
215    #[cfg(feature = "rayon")]
216    pub fn new_par(sorter: S, mut bots: C) -> TreeOwned<C, S>
217    where
218        C::T: Send + Sync,
219        <C::T as Aabb>::Num: Send + Sync,
220    {
221        let j = bots.as_mut();
222        let length = j.len();
223
224        let t = TreeBuilder::new(sorter, j).build_par();
225        let data = t.into_node_data_tree();
226        TreeOwned {
227            inner: bots,
228            nodes: data,
229            length,
230        }
231    }
232
233    pub fn as_tree(&mut self) -> TreeInner<Node<C::T>, S> {
234        let j = self.inner.as_mut();
235        assert_eq!(j.len(), self.length);
236
237        self.nodes.clone().into_tree(AabbPin::from_mut(j))
238    }
239    #[must_use]
240    pub fn as_slice_mut(&mut self) -> AabbPin<&mut [C::T]> {
241        let j = self.inner.as_mut();
242        assert_eq!(j.len(), self.length);
243
244        AabbPin::new(j)
245    }
246    #[must_use]
247    pub fn into_inner(self) -> C {
248        self.inner
249    }
250}
251
252impl<C: Container + Clone, S> TreeOwned<C, S>
253where
254    C::T: Aabb,
255{
256    #[must_use]
257    pub fn clone_inner(&self) -> C {
258        self.inner.clone()
259    }
260}
261
262pub struct TreeBuilder<'a, T, S> {
263    pub bots: &'a mut [T],
264    pub sorter: S,
265    pub num_level: usize,
266    pub num_seq_fallback: usize,
267}
268
269impl<'a, T: Aabb> TreeBuilder<'a, T, NoSorter> {
270    pub fn new_no_sort(bots: &'a mut [T]) -> Self {
271        Self::new(NoSorter, bots)
272    }
273}
274impl<'a, T: Aabb> TreeBuilder<'a, T, DefaultSorter> {
275    pub fn new_default(bots: &'a mut [T]) -> Self {
276        Self::new(DefaultSorter, bots)
277    }
278}
279impl<'a, T: Aabb, S: Sorter<T>> TreeBuilder<'a, T, S> {
280    pub fn new(sorter: S, bots: &'a mut [T]) -> Self {
281        let num_bots = bots.len();
282        let num_seq_fallback = 2_400;
283        TreeBuilder {
284            bots,
285            sorter,
286            num_level: num_level::default(num_bots),
287            num_seq_fallback,
288        }
289    }
290    pub fn build(self) -> TreeInner<Node<'a, T>, S> {
291        let TreeBuilder {
292            bots,
293            sorter,
294            num_level,
295            ..
296        } = self;
297        let total_num_elem = bots.len();
298        let mut buffer = Vec::with_capacity(num_level::num_nodes(num_level));
299        let vistr = TreeBuildVisitor::new(num_level, bots, sorter);
300        vistr.recurse_seq(&mut buffer);
301        TreeInner {
302            nodes: buffer,
303            sorter,
304            total_num_elem,
305        }
306    }
307
308    #[cfg(feature = "rayon")]
309    pub fn build_par(self) -> TreeInner<Node<'a, T>, S>
310    where
311        T: Send,
312        T::Num: Send,
313    {
314        pub fn recurse_par<'a, T: Aabb, S: Sorter<T>>(
315            vistr: TreeBuildVisitor<'a, T, S>,
316            num_seq_fallback: usize,
317            buffer: &mut Vec<Node<'a, T>>,
318        ) where
319            T: Send,
320            T::Num: Send,
321        {
322            let NodeBuildResult { node, rest } = vistr.build_and_next();
323
324            if let Some([left, right]) = rest {
325                if node.get_num_elem() <= num_seq_fallback {
326                    buffer.push(node.finish());
327                    left.recurse_seq(buffer);
328                    right.recurse_seq(buffer);
329                } else {
330                    let (_, mut a) = rayon::join(
331                        || {
332                            buffer.push(node.finish());
333                            recurse_par(left, num_seq_fallback, buffer);
334                        },
335                        || {
336                            let mut f = vec![];
337                            recurse_par(right, num_seq_fallback, &mut f);
338                            f
339                        },
340                    );
341
342                    buffer.append(&mut a);
343                }
344            } else {
345                buffer.push(node.finish());
346            }
347        }
348
349        let TreeBuilder {
350            bots,
351            sorter,
352            num_level,
353            num_seq_fallback,
354        } = self;
355        let total_num_elem = bots.len();
356        let mut buffer = Vec::with_capacity(num_level::num_nodes(num_level));
357        let vistr = TreeBuildVisitor::new(num_level, bots, sorter);
358        recurse_par(vistr, num_seq_fallback, &mut buffer);
359
360        TreeInner {
361            nodes: buffer,
362            sorter,
363            total_num_elem,
364        }
365    }
366}
367
368///
369/// The main tree struct
370///
371#[derive(Clone)]
372#[must_use]
373pub struct TreeInner<N, S> {
374    total_num_elem: usize,
375    ///Stored in pre-order
376    nodes: Vec<N>,
377    sorter: S,
378}
379
380///
381/// [`TreeInner`] type with default node and sorter.
382///
383pub type Tree<'a, T> = TreeInner<Node<'a, T>, DefaultSorter>;
384
385impl<N, Y> TreeInner<N, Y> {
386    pub fn into_sorter<X>(self) -> TreeInner<N, X>
387    where
388        X: From<Y>,
389    {
390        TreeInner {
391            total_num_elem: self.total_num_elem,
392            nodes: self.nodes,
393            sorter: self.sorter.into(),
394        }
395    }
396}
397impl<'a, T: Aabb + 'a, S: Sorter<T>> TreeInner<Node<'a, T>, S> {
398    pub fn into_node_data_tree(self) -> TreeInner<NodeData<T::Num>, S> {
399        self.node_map(|x| NodeData {
400            range: x.range.len(),
401            cont: x.cont,
402            div: x.div,
403            num_elem: x.num_elem,
404        })
405    }
406}
407
408impl<S, H: HasElem> TreeInner<H, S> {
409    pub fn iter_mut(&mut self) -> impl Iterator<Item = AabbPin<&mut H::T>> {
410        self.nodes.iter_mut().flat_map(|x| x.get_elems().iter_mut())
411    }
412}
413
414#[must_use]
415fn as_node_tree<N>(vec: &[N]) -> compt::dfs_order::CompleteTree<N, compt::dfs_order::PreOrder> {
416    compt::dfs_order::CompleteTree::from_preorder(vec).unwrap()
417}
418
419impl<S, H> TreeInner<H, S> {
420    #[inline(always)]
421    pub fn node_map<K>(self, func: impl FnMut(H) -> K) -> TreeInner<K, S> {
422        let sorter = self.sorter;
423        let nodes = self.nodes.into_iter().map(func).collect();
424        TreeInner {
425            nodes,
426            sorter,
427            total_num_elem: self.total_num_elem,
428        }
429    }
430
431    #[must_use]
432    #[inline(always)]
433    pub fn num_levels(&self) -> usize {
434        as_node_tree(&self.nodes).get_height()
435    }
436
437    #[must_use]
438    #[inline(always)]
439    pub fn into_nodes(self) -> Vec<H> {
440        self.nodes
441    }
442
443    #[must_use]
444    #[inline(always)]
445    pub fn num_nodes(&self) -> usize {
446        self.nodes.len()
447    }
448
449    #[must_use]
450    #[inline(always)]
451    pub fn total_num_elem(&self) -> usize {
452        self.total_num_elem
453    }
454
455    #[must_use]
456    #[inline(always)]
457    pub fn get_nodes(&self) -> &[H] {
458        &self.nodes
459    }
460
461    #[must_use]
462    #[inline(always)]
463    pub fn get_nodes_mut(&mut self) -> AabbPin<&mut [H]> {
464        AabbPin::from_mut(&mut self.nodes)
465    }
466
467    #[inline(always)]
468    pub fn vistr_mut(&mut self) -> VistrMutPin<H> {
469        let tree = compt::dfs_order::CompleteTreeMut::from_preorder_mut(&mut self.nodes).unwrap();
470        VistrMutPin::new(tree.vistr_mut())
471    }
472
473    #[inline(always)]
474    pub fn vistr_mut_raw(&mut self) -> compt::dfs_order::VistrMut<H, compt::dfs_order::PreOrder> {
475        let tree = compt::dfs_order::CompleteTreeMut::from_preorder_mut(&mut self.nodes).unwrap();
476        tree.vistr_mut()
477    }
478
479    #[inline(always)]
480    pub fn vistr(&self) -> Vistr<H> {
481        let tree = as_node_tree(&self.nodes);
482
483        tree.vistr()
484    }
485
486    #[must_use]
487    #[inline(always)]
488    pub fn sorter(&self) -> S
489    where
490        S: Copy,
491    {
492        self.sorter
493    }
494}
495
496impl<N: Num, S> TreeInner<NodeData<N>, S> {
497    pub fn into_tree<T: Aabb<Num = N>>(self, bots: AabbPin<&mut [T]>) -> TreeInner<Node<T>, S> {
498        assert_eq!(bots.len(), self.total_num_elem);
499        let mut last = Some(bots);
500        let n = self.node_map(|x| {
501            let (range, rest) = last.take().unwrap().split_at_mut(x.range);
502            last = Some(rest);
503            Node {
504                range,
505                cont: x.cont,
506                div: x.div,
507                num_elem: x.num_elem,
508            }
509        });
510        assert!(last.unwrap().is_empty());
511        n
512    }
513}