moc/moc2d/builder/
maxdepths_cell.rs1use std::cmp::Ordering;
4
5use crate::{
6 moc::{builder::fixed_depth::FixedDepthMocBuilder, range::RangeMOC},
7 moc2d::{Idx, RangeMOC2, RangeMOC2Elem},
8 qty::MocQty,
9};
10
11pub struct FixedDepth2DMocBuilder<T: Idx, Q: MocQty<T>, U: Idx, R: MocQty<U>> {
12 depth_1: u8,
13 depth_2: u8,
14 buff: Vec<(T, U)>,
15 sorted: bool,
16 moc: Option<RangeMOC2<T, Q, U, R>>,
17}
18
19impl<T: Idx, Q: MocQty<T>, U: Idx, R: MocQty<U>> FixedDepth2DMocBuilder<T, Q, U, R> {
20 pub fn new(depth_1: u8, depth_2: u8, buf_capacity: Option<usize>) -> Self {
21 Self {
22 depth_1,
23 depth_2,
24 buff: Vec::with_capacity(buf_capacity.unwrap_or(100_000)),
25 sorted: true,
26 moc: None,
27 }
28 }
29
30 pub fn push(&mut self, idx_1: T, idx_2: U) {
31 if let Some((h1, h2)) = self.buff.last() {
32 if *h1 == idx_1 && *h2 == idx_2 {
33 return;
34 } else if self.sorted && *h1 > idx_1 {
35 self.sorted = false;
36 }
37 }
38 self.buff.push((idx_1, idx_2));
39 if self.buff.len() == self.buff.capacity() {
40 self.drain_buffer();
41 }
42 }
43
44 pub fn into_moc(mut self) -> RangeMOC2<T, Q, U, R> {
45 self.drain_buffer();
46 let depth_1 = self.depth_1;
47 let depth_2 = self.depth_2;
48 self
49 .moc
50 .unwrap_or_else(|| RangeMOC2::new(depth_1, depth_2, Default::default()))
51 }
52
53 fn drain_buffer(&mut self) {
54 if !self.sorted {
55 self
57 .buff
58 .sort_unstable_by(|(h1_a, _), (h1_b, _)| h1_a.cmp(h1_b));
59 }
60 let new_moc = self.buff_to_moc();
61 self.clear_buff();
62 let merged_moc = if let Some(prev_moc) = &self.moc {
63 prev_moc.or(&new_moc)
64 } else {
65 new_moc
66 };
67 self.moc.replace(merged_moc);
68 }
69
70 fn buff_to_moc(&self) -> RangeMOC2<T, Q, U, R> {
71 let mut range_mocs: Vec<RangeMOC2Elem<T, Q, U, R>> = Vec::with_capacity(self.buff.len());
75
76 let mut it = self.buff.iter();
78 if let Some((from_1, from_2)) = it.next() {
79 let mut from_1 = *from_1;
80 let from_2 = *from_2;
81 let mut moc_builder_1 = FixedDepthMocBuilder::<T, Q>::new(self.depth_1, Some(64));
82 moc_builder_1.push(from_1);
83 let mut moc_builder_2 = FixedDepthMocBuilder::<U, R>::new(self.depth_2, Some(1000));
84 moc_builder_2.push(from_2);
85 let mut prev_moc_2: Option<RangeMOC<U, R>> = None;
86 for (curr_1, curr_2) in it {
87 match from_1.cmp(curr_1) {
88 Ordering::Equal => moc_builder_2.push(*curr_2), Ordering::Less => {
90 let moc_2 = moc_builder_2.into_moc();
92 debug_assert!(!moc_2.is_empty());
93 if let Some(p_moc_2) = prev_moc_2.as_ref() {
95 if !moc_2.eq(p_moc_2) {
96 let p_moc_1 = moc_builder_1.into_moc();
98 let p_moc_2 = prev_moc_2.replace(moc_2).unwrap();
99 debug_assert!(!p_moc_1.is_empty());
100 debug_assert!(!p_moc_2.is_empty());
101 range_mocs.push(RangeMOC2Elem::new(p_moc_1, p_moc_2));
102 moc_builder_1 = FixedDepthMocBuilder::<T, Q>::new(self.depth_1, Some(64));
103 moc_builder_1.push(from_1);
104 } else {
105 moc_builder_1.push(from_1);
106 }
107 } else {
108 prev_moc_2 = Some(moc_2);
112 }
114 moc_builder_2 = FixedDepthMocBuilder::<U, R>::new(self.depth_2, Some(1000));
116 moc_builder_2.push(*curr_2);
117 from_1 = *curr_1;
118 }
119 Ordering::Greater => unreachable!(), }
121 }
122 let moc_2 = moc_builder_2.into_moc();
123 if let Some(p_moc_2) = prev_moc_2.as_ref() {
124 if !moc_2.eq(p_moc_2) {
125 let p_moc_1 = moc_builder_1.into_moc();
127 let p_moc_2 = prev_moc_2.replace(moc_2).unwrap();
128 debug_assert!(!p_moc_1.is_empty());
129 debug_assert!(!p_moc_2.is_empty());
130 range_mocs.push(RangeMOC2Elem::new(p_moc_1, p_moc_2));
131 moc_builder_1 = FixedDepthMocBuilder::<T, Q>::new(self.depth_1, Some(64));
132 moc_builder_1.push(from_1);
133 let moc_1 = moc_builder_1.into_moc();
134 range_mocs.push(RangeMOC2Elem::new(moc_1, prev_moc_2.unwrap()));
135 } else {
136 moc_builder_1.push(from_1);
137 let moc_1 = moc_builder_1.into_moc();
138 debug_assert!(!moc_1.is_empty());
139 debug_assert!(!moc_2.is_empty());
140 range_mocs.push(RangeMOC2Elem::new(moc_1, moc_2));
141 }
142 } else {
143 let moc_1 = moc_builder_1.into_moc();
144 debug_assert!(!moc_1.is_empty());
145 debug_assert!(!moc_2.is_empty());
146 range_mocs.push(RangeMOC2Elem::new(moc_1, moc_2));
147 }
148 }
149 RangeMOC2::new(self.depth_1, self.depth_2, range_mocs)
150 }
151
152 fn clear_buff(&mut self) {
153 self.sorted = true;
154 self.buff.clear();
155 }
156}
157
158#[cfg(test)]
159mod tests {
160
161 use super::FixedDepth2DMocBuilder;
162 use crate::qty::{Frequency, Hpx};
163
164 #[test]
165 fn test_build2dmoc_fixeddepth() {
166 let mut builder =
167 FixedDepth2DMocBuilder::<u64, Frequency<u64>, u64, Hpx<u64>>::new(10, 11, None);
168 builder.push(1, 1);
169 builder.push(2, 3);
170 builder.push(4, 6);
171 let moc2d = builder.into_moc();
172 assert_eq!(moc2d.compute_n_ranges(), 6);
173 }
180}