1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
use crate::tree::*;
use crate::inner_prelude::*;




enum ReOrderStrat{
    Aux,
    NoAux
}


///Builder for a DinoTree
pub struct DinoTreeGenericBuilder<'a, A: AxisTrait, T:HasAabb> {
    axis: A,
    bots: &'a mut [T],
    rebal_strat: BinStrat,
    height: usize,
    height_switch_seq: usize,
}

impl<'a, A: AxisTrait, T:HasAabbMut> DinoTreeGenericBuilder<'a, A, T> {
    #[inline]
    pub fn new(axis: A, bots: &'a mut [T]) -> DinoTreeGenericBuilder<'a, A,T> {
        let rebal_strat = BinStrat::Checked;
        let height = compute_tree_height_heuristic(bots.len());
        let height_switch_seq = default_level_switch_sequential();

        let bots=unsafe{&mut *(bots as *mut [T] as *mut [T])};
        DinoTreeGenericBuilder {
            axis,
            bots,
            rebal_strat,
            height,
            height_switch_seq,
        }
    }


    #[inline]
    pub fn build_seq_aux(self)->DinoTreeGeneric<'a,A,T>{
        self.build_inner(
            par::Sequential,
            DefaultSorter,
            &mut SplitterEmpty,
            ReOrderStrat::Aux
        )
    }

    #[inline]
    pub fn build_par_aux(self)->DinoTreeGeneric<'a,A,T>{
        let dlevel = compute_default_level_switch_sequential(self.height_switch_seq, self.height);
        self.build_inner(dlevel, DefaultSorter, &mut SplitterEmpty,ReOrderStrat::Aux)
    }

    #[inline]
    pub fn build_seq(self) -> DinoTreeGeneric<'a, A, T> {
        self.build_inner(
            par::Sequential,
            DefaultSorter,
            &mut SplitterEmpty,
            ReOrderStrat::NoAux
        )
    }

    

    #[inline]
    pub fn build_par(self) -> DinoTreeGeneric<'a, A, T> {
        let dlevel = compute_default_level_switch_sequential(self.height_switch_seq, self.height);
        self.build_inner(dlevel, DefaultSorter, &mut SplitterEmpty,ReOrderStrat::NoAux)
    }

    fn build_inner<JJ: par::Joiner, K: Splitter + Send>(
        mut self,
        par: JJ,
        sorter: impl Sorter,
        ka: &mut K,
        reorder_type:ReOrderStrat
    ) -> DinoTreeGeneric<'a, A, T> {
        let axis = self.axis;

        let height = self.height;
        let binstrat = self.rebal_strat;

        let bots2 = unsafe { &mut *(self.bots as *mut [_]) };
        
        let num_bots = self.bots.len();
        let max = core::u32::MAX;

        assert!(
            num_bots < max as usize,
            "problems of size {} are bigger are not supported",
            max
        );

        let mut conts: Vec<_> = self
            .bots
            .iter()
            .enumerate()
            .map(move |(index, k)| BBoxSendSync {
                rect: *k.get().rect,
                inner: index as u32,
            })
            .collect();

        let new_tree = {
            let cont_tree = ContTree::new(axis, par, &mut conts, sorter, ka, height, binstrat);

            {
                let mut indicies=reorder::swap_index(conts.iter().map(|a|a.inner));
                match reorder_type{
                    ReOrderStrat::Aux=>{
                        reorder::reorder_index_aux(&mut self.bots, &mut indicies);
                    },
                    ReOrderStrat::NoAux=>{
                        reorder::reorder_index(&mut self.bots, &mut indicies);        
                    }
                }
                
            }    

            let new_nodes = {
                let mut rest: Option<&mut [_]> = Some(&mut self.bots);
                let mut new_nodes = Vec::with_capacity(cont_tree.tree.get_nodes().len());
                for node in cont_tree.tree.get_nodes().iter() {
                    let (b, rest2) = rest.take().unwrap().split_at_mut(node.get().bots.len());
                    rest = Some(rest2);
                    let b = tools::Unique::new(ElemSlice::from_slice_mut(b) as *mut _).unwrap();
                    new_nodes.push(Node {
                        range: b,
                        cont: node.cont,
                        div: node.div,
                    })
                }
                new_nodes
            };

            compt::dfs_order::CompleteTreeContainer::from_preorder(new_nodes).unwrap()
        };
        let mover = conts
            .drain(..)
            .map(|a| a.inner)
            .collect();

        DinoTreeGeneric {
            mover,
            axis,
            bots: bots2,
            nodes: new_tree,
        }
    }
}


///Version of dinotree that does not make a copy of all the elements.
pub struct DinoTreeGeneric<'a, A: AxisTrait, T: HasAabbMut> {
    axis: A,
    bots: &'a mut [T],
    nodes: compt::dfs_order::CompleteTreeContainer<Node<T>, compt::dfs_order::PreOrder>,
    mover: Vec<u32>,
}

impl<'a, A: AxisTrait, T: HasAabbMut> DinoTreeGeneric<'a, A, T> {
    ///Returns the bots to their original ordering. This is what you would call after you used this tree
    ///to make the changes you made while querying the tree (through use of vistr_mut) be copied back into the original list.
    #[inline]
    pub fn into_original(mut self) -> &'a mut [T] {
        reorder::reorder_index(self.bots, &mut self.mover);
        self.bots
    }

    ///Returns the elements of the tree is the order they are in the tree.
    pub fn get_bots_mut(&mut self)->&mut [T]{
        self.bots
    }

    pub fn get_bots(&self)->&[T]{
        self.bots
    }
}


impl<'a,A:AxisTrait,T:HasAabbMut> DinoTreeRefTrait for DinoTreeGeneric<'a,A,T>{
    type Item=T;
    type Axis=A;
    type Num=T::Num;
    type Inner=T::Inner;
    
    fn axis(&self)->Self::Axis{
        self.axis
    }
    fn vistr(&self)->Vistr<Self::Item>{
        Vistr {
            inner: self.nodes.vistr(),
        }
    }

    ///Return the height of the dinotree.
    #[inline]
    fn height(&self) -> usize
    {
        self.nodes.get_height()
    }

    ///Return the number of nodes of the dinotree.
    #[inline]
    fn num_nodes(&self) -> usize
    {
        self.nodes.get_nodes().len()
    }

    ///Return the number of bots in the tree.
    #[inline]
    fn num_bots(&self) -> usize
    {
        self.bots.len()
    }

}


impl<'a,A:AxisTrait,T:HasAabbMut> DinoTreeRefMutTrait for DinoTreeGeneric<'a,A,T>{    
    fn vistr_mut(&mut self)->VistrMut<Self::Item>{
        VistrMut {
            inner: self.nodes.vistr_mut(),
        }
    }
}