1use crate::interval::Interval;
19use crate::tree::{DefaultMetric, Leaf, Metric, Node, NodeInfo, TreeBuilder};
20use std::cmp::min;
21use std::mem;
22
23pub type Breaks = Node<BreaksInfo>;
25
26const MIN_LEAF: usize = 32;
27const MAX_LEAF: usize = 64;
28
29#[derive(Clone, Debug, Default, PartialEq, Eq)]
33pub struct BreaksLeaf {
34 len: usize,
36 data: Vec<usize>,
38}
39
40#[derive(Clone, Debug)]
42pub struct BreaksInfo(usize);
43
44impl Leaf for BreaksLeaf {
45 fn len(&self) -> usize {
46 self.len
47 }
48
49 fn is_ok_child(&self) -> bool {
50 self.data.len() >= MIN_LEAF
51 }
52
53 fn push_maybe_split(&mut self, other: &BreaksLeaf, iv: Interval) -> Option<BreaksLeaf> {
54 let (start, end) = iv.start_end();
56 for &v in &other.data {
57 if start < v && v <= end {
58 self.data.push(v - start + self.len);
59 }
60 }
61 self.len += min(end, other.len()) - start;
63
64 if self.data.len() <= MAX_LEAF {
65 None
66 } else {
67 let splitpoint = self.data.len() / 2; let splitpoint_units = self.data[splitpoint - 1];
69
70 let mut new = self.data.split_off(splitpoint);
71 for x in &mut new {
72 *x -= splitpoint_units;
73 }
74
75 let new_len = self.len - splitpoint_units;
76 self.len = splitpoint_units;
77 Some(BreaksLeaf { len: new_len, data: new })
78 }
79 }
80}
81
82impl NodeInfo for BreaksInfo {
83 type L = BreaksLeaf;
84
85 fn accumulate(&mut self, other: &Self) {
86 self.0 += other.0;
87 }
88
89 fn compute_info(l: &BreaksLeaf) -> BreaksInfo {
90 BreaksInfo(l.data.len())
91 }
92}
93
94impl DefaultMetric for BreaksInfo {
95 type DefaultMetric = BreaksBaseMetric;
96}
97
98impl BreaksLeaf {
99 #[doc(hidden)]
101 pub fn get_data_cloned(&self) -> Vec<usize> {
102 self.data.clone()
103 }
104}
105
106#[derive(Copy, Clone)]
107pub struct BreaksMetric(());
108
109impl Metric<BreaksInfo> for BreaksMetric {
110 fn measure(info: &BreaksInfo, _: usize) -> usize {
111 info.0
112 }
113
114 fn to_base_units(l: &BreaksLeaf, in_measured_units: usize) -> usize {
115 if in_measured_units > l.data.len() {
116 l.len + 1
117 } else if in_measured_units == 0 {
118 0
119 } else {
120 l.data[in_measured_units - 1]
121 }
122 }
123
124 fn from_base_units(l: &BreaksLeaf, in_base_units: usize) -> usize {
125 match l.data.binary_search(&in_base_units) {
126 Ok(n) => n + 1,
127 Err(n) => n,
128 }
129 }
130
131 fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
132 l.data.binary_search(&offset).is_ok()
133 }
134
135 fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
136 for i in 0..l.data.len() {
137 if offset <= l.data[i] {
138 if i == 0 {
139 return None;
140 } else {
141 return Some(l.data[i - 1]);
142 }
143 }
144 }
145 l.data.last().cloned()
146 }
147
148 fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
149 let n = match l.data.binary_search(&offset) {
150 Ok(n) => n + 1,
151 Err(n) => n,
152 };
153
154 if n == l.data.len() {
155 None
156 } else {
157 Some(l.data[n])
158 }
159 }
160
161 fn can_fragment() -> bool {
162 true
163 }
164}
165
166#[derive(Copy, Clone)]
167pub struct BreaksBaseMetric(());
168
169impl Metric<BreaksInfo> for BreaksBaseMetric {
170 fn measure(_: &BreaksInfo, len: usize) -> usize {
171 len
172 }
173
174 fn to_base_units(_: &BreaksLeaf, in_measured_units: usize) -> usize {
175 in_measured_units
176 }
177
178 fn from_base_units(_: &BreaksLeaf, in_base_units: usize) -> usize {
179 in_base_units
180 }
181
182 fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
183 BreaksMetric::is_boundary(l, offset)
184 }
185
186 fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
187 BreaksMetric::prev(l, offset)
188 }
189
190 fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
191 BreaksMetric::next(l, offset)
192 }
193
194 fn can_fragment() -> bool {
195 true
196 }
197}
198
199impl Breaks {
202 pub fn new_no_break(len: usize) -> Breaks {
205 let leaf = BreaksLeaf { len, data: vec![] };
206 Node::from_leaf(leaf)
207 }
208}
209
210pub struct BreakBuilder {
211 b: TreeBuilder<BreaksInfo>,
212 leaf: BreaksLeaf,
213}
214
215impl Default for BreakBuilder {
216 fn default() -> BreakBuilder {
217 BreakBuilder { b: TreeBuilder::new(), leaf: BreaksLeaf::default() }
218 }
219}
220
221impl BreakBuilder {
222 pub fn new() -> BreakBuilder {
223 BreakBuilder::default()
224 }
225
226 pub fn add_break(&mut self, len: usize) {
227 if self.leaf.data.len() == MAX_LEAF {
228 let leaf = mem::replace(&mut self.leaf, BreaksLeaf::default());
229 self.b.push(Node::from_leaf(leaf));
230 }
231 self.leaf.len += len;
232 self.leaf.data.push(self.leaf.len);
233 }
234
235 pub fn add_no_break(&mut self, len: usize) {
236 self.leaf.len += len;
237 }
238
239 pub fn build(mut self) -> Breaks {
240 self.b.push(Node::from_leaf(self.leaf));
241 self.b.build()
242 }
243}
244
245#[cfg(test)]
246mod tests {
247 use crate::breaks::{BreakBuilder, BreaksInfo, BreaksLeaf, BreaksMetric};
248 use crate::interval::Interval;
249 use crate::tree::{Cursor, Node};
250
251 fn gen(n: usize) -> Node<BreaksInfo> {
252 let mut node = Node::default();
253 let mut b = BreakBuilder::new();
254 b.add_break(10);
255 let testnode = b.build();
256 if n == 1 {
257 return testnode;
258 }
259 for _ in 0..n {
260 let len = node.len();
261 let empty_interval_at_end = Interval::new(len, len);
262 node.edit(empty_interval_at_end, testnode.clone());
263 }
264 node
265 }
266
267 #[test]
268 fn empty() {
269 let n = gen(0);
270 assert_eq!(0, n.len());
271 }
272
273 #[test]
274 fn fromleaf() {
275 let testnode = gen(1);
276 assert_eq!(10, testnode.len());
277 }
278
279 #[test]
280 fn one() {
281 let testleaf = BreaksLeaf { len: 10, data: vec![10] };
282 let testnode = Node::<BreaksInfo>::from_leaf(testleaf.clone());
283 assert_eq!(10, testnode.len());
284 let mut c = Cursor::new(&testnode, 0);
285 assert_eq!(c.get_leaf().unwrap().0, &testleaf);
286 assert_eq!(10, c.next::<BreaksMetric>().unwrap());
287 assert!(c.next::<BreaksMetric>().is_none());
288 c.set(0);
289 assert!(!c.is_boundary::<BreaksMetric>());
290 c.set(1);
291 assert!(!c.is_boundary::<BreaksMetric>());
292 c.set(10);
293 assert!(c.is_boundary::<BreaksMetric>());
294 assert!(c.prev::<BreaksMetric>().is_none());
295 }
296
297 #[test]
298 fn concat() {
299 let left = gen(1);
300 let right = gen(1);
301 let node = Node::concat(left.clone(), right);
302 assert_eq!(node.len(), 20);
303 let mut c = Cursor::new(&node, 0);
304 assert_eq!(10, c.next::<BreaksMetric>().unwrap());
305 assert_eq!(20, c.next::<BreaksMetric>().unwrap());
306 assert!(c.next::<BreaksMetric>().is_none());
307 }
308
309 #[test]
310 fn larger() {
311 let node = gen(100);
312 assert_eq!(node.len(), 1000);
313 }
314
315 #[test]
316 fn default_metric_test() {
317 use super::BreaksBaseMetric;
318
319 let breaks = gen(10);
320 assert_eq!(
321 breaks.convert_metrics::<BreaksBaseMetric, BreaksMetric>(5),
322 breaks.count::<BreaksMetric>(5)
323 );
324 assert_eq!(
325 breaks.convert_metrics::<BreaksMetric, BreaksBaseMetric>(7),
326 breaks.count_base_units::<BreaksMetric>(7)
327 );
328 }
329}