1use super::*;
2use arrayvec::ArrayVec;
3use std::{cmp::Ordering, mem, sync::Arc};
4
5#[derive(Clone)]
6struct StackEntry<'a, T: Item, D> {
7 tree: &'a SumTree<T>,
8 index: usize,
9 position: D,
10}
11
12#[derive(Clone)]
13pub struct Cursor<'a, T: Item, D> {
14 tree: &'a SumTree<T>,
15 stack: ArrayVec<StackEntry<'a, T, D>, 16>,
16 position: D,
17 did_seek: bool,
18 at_end: bool,
19}
20
21impl<'a, T, D> Cursor<'a, T, D>
22where
23 T: Item,
24 D: Dimension<'a, T::Summary>,
25{
26 pub fn new(tree: &'a SumTree<T>) -> Self {
27 Self {
28 tree,
29 stack: ArrayVec::new(),
30 position: D::default(),
31 did_seek: false,
32 at_end: false,
33 }
34 }
35
36 fn reset(&mut self) {
37 self.did_seek = false;
38 self.at_end = false;
39 self.stack.truncate(0);
40 self.position = D::default();
41 }
42
43 pub fn start(&self) -> &D {
44 &self.position
45 }
46
47 pub fn end(&self, cx: &<T::Summary as Summary>::Context) -> D {
48 if let Some(item_summary) = self.item_summary() {
49 let mut end = self.start().clone();
50 end.add_summary(item_summary, cx);
51 end
52 } else {
53 self.start().clone()
54 }
55 }
56
57 pub fn item(&self) -> Option<&'a T> {
58 assert!(self.did_seek, "Must seek before calling this method");
59 if let Some(entry) = self.stack.last() {
60 match *entry.tree.0 {
61 Node::Leaf { ref items, .. } => {
62 if entry.index == items.len() {
63 None
64 } else {
65 Some(&items[entry.index])
66 }
67 }
68 _ => unreachable!(),
69 }
70 } else {
71 None
72 }
73 }
74
75 pub fn item_summary(&self) -> Option<&'a T::Summary> {
76 assert!(self.did_seek, "Must seek before calling this method");
77 if let Some(entry) = self.stack.last() {
78 match *entry.tree.0 {
79 Node::Leaf {
80 ref item_summaries, ..
81 } => {
82 if entry.index == item_summaries.len() {
83 None
84 } else {
85 Some(&item_summaries[entry.index])
86 }
87 }
88 _ => unreachable!(),
89 }
90 } else {
91 None
92 }
93 }
94
95 pub fn prev_item(&self) -> Option<&'a T> {
96 assert!(self.did_seek, "Must seek before calling this method");
97 if let Some(entry) = self.stack.last() {
98 if entry.index == 0 {
99 if let Some(prev_leaf) = self.prev_leaf() {
100 Some(prev_leaf.0.items().last().unwrap())
101 } else {
102 None
103 }
104 } else {
105 match *entry.tree.0 {
106 Node::Leaf { ref items, .. } => Some(&items[entry.index - 1]),
107 _ => unreachable!(),
108 }
109 }
110 } else if self.at_end {
111 self.tree.last()
112 } else {
113 None
114 }
115 }
116
117 fn prev_leaf(&self) -> Option<&'a SumTree<T>> {
118 for entry in self.stack.iter().rev().skip(1) {
119 if entry.index != 0 {
120 match *entry.tree.0 {
121 Node::Internal {
122 ref child_trees, ..
123 } => return Some(child_trees[entry.index - 1].rightmost_leaf()),
124 Node::Leaf { .. } => unreachable!(),
125 };
126 }
127 }
128 None
129 }
130
131 pub fn prev(&mut self, cx: &<T::Summary as Summary>::Context) {
132 assert!(self.did_seek, "Must seek before calling this method");
133
134 if self.at_end {
135 self.position = D::default();
136 self.descend_to_last_item(self.tree, cx);
137 self.at_end = false;
138 } else {
139 while let Some(entry) = self.stack.pop() {
140 if entry.index > 0 {
141 let new_index = entry.index - 1;
142
143 if let Some(StackEntry { position, .. }) = self.stack.last() {
144 self.position = position.clone();
145 } else {
146 self.position = D::default();
147 }
148
149 match entry.tree.0.as_ref() {
150 Node::Internal {
151 child_trees,
152 child_summaries,
153 ..
154 } => {
155 for summary in &child_summaries[0..new_index] {
156 self.position.add_summary(summary, cx);
157 }
158 self.stack.push(StackEntry {
159 tree: entry.tree,
160 index: new_index,
161 position: self.position.clone(),
162 });
163 self.descend_to_last_item(&child_trees[new_index], cx);
164 }
165 Node::Leaf { item_summaries, .. } => {
166 for item_summary in &item_summaries[0..new_index] {
167 self.position.add_summary(item_summary, cx);
168 }
169 self.stack.push(StackEntry {
170 tree: entry.tree,
171 index: new_index,
172 position: self.position.clone(),
173 });
174 }
175 }
176
177 break;
178 }
179 }
180 }
181 }
182
183 pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
184 self.next_internal(|_| true, cx)
185 }
186
187 fn next_internal<F>(&mut self, filter_node: F, cx: &<T::Summary as Summary>::Context)
188 where
189 F: Fn(&T::Summary) -> bool,
190 {
191 let mut descend = false;
192
193 if self.stack.is_empty() && !self.at_end {
194 self.stack.push(StackEntry {
195 tree: self.tree,
196 index: 0,
197 position: D::default(),
198 });
199 descend = true;
200 self.did_seek = true;
201 }
202
203 while self.stack.len() > 0 {
204 let new_subtree = {
205 let entry = self.stack.last_mut().unwrap();
206 match entry.tree.0.as_ref() {
207 Node::Internal {
208 child_trees,
209 child_summaries,
210 ..
211 } => {
212 if !descend {
213 entry.position = self.position.clone();
214 entry.index += 1;
215 }
216
217 while entry.index < child_summaries.len() {
218 let next_summary = &child_summaries[entry.index];
219 if filter_node(next_summary) {
220 break;
221 } else {
222 self.position.add_summary(next_summary, cx);
223 }
224 entry.index += 1;
225 }
226
227 child_trees.get(entry.index)
228 }
229 Node::Leaf { item_summaries, .. } => {
230 if !descend {
231 let item_summary = &item_summaries[entry.index];
232 self.position.add_summary(item_summary, cx);
233 entry.position.add_summary(item_summary, cx);
234 entry.index += 1;
235 }
236
237 loop {
238 if let Some(next_item_summary) = item_summaries.get(entry.index) {
239 if filter_node(next_item_summary) {
240 return;
241 } else {
242 self.position.add_summary(next_item_summary, cx);
243 entry.position.add_summary(next_item_summary, cx);
244 entry.index += 1;
245 }
246 } else {
247 break None;
248 }
249 }
250 }
251 }
252 };
253
254 if let Some(subtree) = new_subtree {
255 descend = true;
256 self.stack.push(StackEntry {
257 tree: subtree,
258 index: 0,
259 position: self.position.clone(),
260 });
261 } else {
262 descend = false;
263 self.stack.pop();
264 }
265 }
266
267 self.at_end = self.stack.is_empty();
268 debug_assert!(self.stack.is_empty() || self.stack.last().unwrap().tree.0.is_leaf());
269 }
270
271 fn descend_to_last_item(
272 &mut self,
273 mut subtree: &'a SumTree<T>,
274 cx: &<T::Summary as Summary>::Context,
275 ) {
276 self.did_seek = true;
277 loop {
278 match subtree.0.as_ref() {
279 Node::Internal {
280 child_trees,
281 child_summaries,
282 ..
283 } => {
284 for summary in &child_summaries[0..child_summaries.len() - 1] {
285 self.position.add_summary(summary, cx);
286 }
287
288 self.stack.push(StackEntry {
289 tree: subtree,
290 index: child_trees.len() - 1,
291 position: self.position.clone(),
292 });
293 subtree = child_trees.last().unwrap();
294 }
295 Node::Leaf { item_summaries, .. } => {
296 let last_index = item_summaries.len().saturating_sub(1);
297 for item_summary in &item_summaries[0..last_index] {
298 self.position.add_summary(item_summary, cx);
299 }
300 self.stack.push(StackEntry {
301 tree: subtree,
302 index: last_index,
303 position: self.position.clone(),
304 });
305 break;
306 }
307 }
308 }
309 }
310}
311
312impl<'a, T, D> Cursor<'a, T, D>
313where
314 T: Item,
315 D: Dimension<'a, T::Summary>,
316{
317 pub fn seek<Target>(
318 &mut self,
319 pos: &Target,
320 bias: Bias,
321 cx: &<T::Summary as Summary>::Context,
322 ) -> bool
323 where
324 Target: SeekTarget<'a, T::Summary, D>,
325 {
326 self.reset();
327 self.seek_internal(pos, bias, &mut (), cx)
328 }
329
330 pub fn seek_forward<Target>(
331 &mut self,
332 pos: &Target,
333 bias: Bias,
334 cx: &<T::Summary as Summary>::Context,
335 ) -> bool
336 where
337 Target: SeekTarget<'a, T::Summary, D>,
338 {
339 self.seek_internal(pos, bias, &mut (), cx)
340 }
341
342 pub fn slice<Target>(
343 &mut self,
344 end: &Target,
345 bias: Bias,
346 cx: &<T::Summary as Summary>::Context,
347 ) -> SumTree<T>
348 where
349 Target: SeekTarget<'a, T::Summary, D>,
350 {
351 let mut slice = SliceSeekAggregate {
352 tree: SumTree::new(),
353 leaf_items: ArrayVec::new(),
354 leaf_item_summaries: ArrayVec::new(),
355 leaf_summary: T::Summary::default(),
356 };
357 self.seek_internal(end, bias, &mut slice, cx);
358 slice.tree
359 }
360
361 pub fn suffix(&mut self, cx: &<T::Summary as Summary>::Context) -> SumTree<T> {
362 self.slice(&End::new(), Bias::Right, cx)
363 }
364
365 pub fn summary<Target, Output>(
366 &mut self,
367 end: &Target,
368 bias: Bias,
369 cx: &<T::Summary as Summary>::Context,
370 ) -> Output
371 where
372 Target: SeekTarget<'a, T::Summary, D>,
373 Output: Dimension<'a, T::Summary>,
374 {
375 let mut summary = SummarySeekAggregate(Output::default());
376 self.seek_internal(end, bias, &mut summary, cx);
377 summary.0
378 }
379
380 fn seek_internal(
381 &mut self,
382 target: &dyn SeekTarget<'a, T::Summary, D>,
383 bias: Bias,
384 aggregate: &mut dyn SeekAggregate<'a, T>,
385 cx: &<T::Summary as Summary>::Context,
386 ) -> bool {
387 debug_assert!(
388 target.cmp(&self.position, cx) >= Ordering::Equal,
389 "cannot seek backward from {:?} to {:?}",
390 self.position,
391 target
392 );
393
394 if !self.did_seek {
395 self.did_seek = true;
396 self.stack.push(StackEntry {
397 tree: self.tree,
398 index: 0,
399 position: Default::default(),
400 });
401 }
402
403 let mut ascending = false;
404 'outer: while let Some(entry) = self.stack.last_mut() {
405 match *entry.tree.0 {
406 Node::Internal {
407 ref child_summaries,
408 ref child_trees,
409 ..
410 } => {
411 if ascending {
412 entry.index += 1;
413 }
414
415 for (child_tree, child_summary) in child_trees[entry.index..]
416 .iter()
417 .zip(&child_summaries[entry.index..])
418 {
419 let mut child_end = self.position.clone();
420 child_end.add_summary(&child_summary, cx);
421
422 let comparison = target.cmp(&child_end, cx);
423 if comparison == Ordering::Greater
424 || (comparison == Ordering::Equal && bias == Bias::Right)
425 {
426 self.position = child_end;
427 aggregate.push_tree(child_tree, child_summary, cx);
428 entry.index += 1;
429 entry.position = self.position.clone();
430 } else {
431 self.stack.push(StackEntry {
432 tree: child_tree,
433 index: 0,
434 position: self.position.clone(),
435 });
436 ascending = false;
437 continue 'outer;
438 }
439 }
440 }
441 Node::Leaf {
442 ref items,
443 ref item_summaries,
444 ..
445 } => {
446 aggregate.begin_leaf();
447
448 for (item, item_summary) in items[entry.index..]
449 .iter()
450 .zip(&item_summaries[entry.index..])
451 {
452 let mut child_end = self.position.clone();
453 child_end.add_summary(item_summary, cx);
454
455 let comparison = target.cmp(&child_end, cx);
456 if comparison == Ordering::Greater
457 || (comparison == Ordering::Equal && bias == Bias::Right)
458 {
459 self.position = child_end;
460 aggregate.push_item(item, item_summary, cx);
461 entry.index += 1;
462 } else {
463 aggregate.end_leaf(cx);
464 break 'outer;
465 }
466 }
467
468 aggregate.end_leaf(cx);
469 }
470 }
471
472 self.stack.pop();
473 ascending = true;
474 }
475
476 self.at_end = self.stack.is_empty();
477 debug_assert!(self.stack.is_empty() || self.stack.last().unwrap().tree.0.is_leaf());
478
479 let mut end = self.position.clone();
480 if bias == Bias::Left {
481 if let Some(summary) = self.item_summary() {
482 end.add_summary(summary, cx);
483 }
484 }
485
486 target.cmp(&end, cx) == Ordering::Equal
487 }
488}
489
490impl<'a, T, S, D> Iterator for Cursor<'a, T, D>
491where
492 T: Item<Summary = S>,
493 S: Summary<Context = ()>,
494 D: Dimension<'a, T::Summary>,
495{
496 type Item = &'a T;
497
498 fn next(&mut self) -> Option<Self::Item> {
499 if !self.did_seek {
500 self.next(&());
501 }
502
503 if let Some(item) = self.item() {
504 self.next(&());
505 Some(item)
506 } else {
507 None
508 }
509 }
510}
511
512pub struct FilterCursor<'a, F: Fn(&T::Summary) -> bool, T: Item, D> {
513 cursor: Cursor<'a, T, D>,
514 filter_node: F,
515}
516
517impl<'a, F, T, D> FilterCursor<'a, F, T, D>
518where
519 F: Fn(&T::Summary) -> bool,
520 T: Item,
521 D: Dimension<'a, T::Summary>,
522{
523 pub fn new(
524 tree: &'a SumTree<T>,
525 filter_node: F,
526 cx: &<T::Summary as Summary>::Context,
527 ) -> Self {
528 let mut cursor = tree.cursor::<D>();
529 cursor.next_internal(&filter_node, cx);
530 Self {
531 cursor,
532 filter_node,
533 }
534 }
535
536 pub fn start(&self) -> &D {
537 self.cursor.start()
538 }
539
540 pub fn item(&self) -> Option<&'a T> {
541 self.cursor.item()
542 }
543
544 pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
545 self.cursor.next_internal(&self.filter_node, cx);
546 }
547}
548
549impl<'a, F, T, S, U> Iterator for FilterCursor<'a, F, T, U>
550where
551 F: Fn(&T::Summary) -> bool,
552 T: Item<Summary = S>,
553 S: Summary<Context = ()>,
554 U: Dimension<'a, T::Summary>,
555{
556 type Item = &'a T;
557
558 fn next(&mut self) -> Option<Self::Item> {
559 if let Some(item) = self.item() {
560 self.cursor.next_internal(&self.filter_node, &());
561 Some(item)
562 } else {
563 None
564 }
565 }
566}
567
568trait SeekAggregate<'a, T: Item> {
569 fn begin_leaf(&mut self);
570 fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context);
571 fn push_item(
572 &mut self,
573 item: &'a T,
574 summary: &'a T::Summary,
575 cx: &<T::Summary as Summary>::Context,
576 );
577 fn push_tree(
578 &mut self,
579 tree: &'a SumTree<T>,
580 summary: &'a T::Summary,
581 cx: &<T::Summary as Summary>::Context,
582 );
583}
584
585struct SliceSeekAggregate<T: Item> {
586 tree: SumTree<T>,
587 leaf_items: ArrayVec<T, { 2 * TREE_BASE }>,
588 leaf_item_summaries: ArrayVec<T::Summary, { 2 * TREE_BASE }>,
589 leaf_summary: T::Summary,
590}
591
592struct SummarySeekAggregate<D>(D);
593
594impl<'a, T: Item> SeekAggregate<'a, T> for () {
595 fn begin_leaf(&mut self) {}
596 fn end_leaf(&mut self, _: &<T::Summary as Summary>::Context) {}
597 fn push_item(&mut self, _: &T, _: &T::Summary, _: &<T::Summary as Summary>::Context) {}
598 fn push_tree(&mut self, _: &SumTree<T>, _: &T::Summary, _: &<T::Summary as Summary>::Context) {}
599}
600
601impl<'a, T: Item> SeekAggregate<'a, T> for SliceSeekAggregate<T> {
602 fn begin_leaf(&mut self) {}
603 fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context) {
604 self.tree.push_tree(
605 SumTree(Arc::new(Node::Leaf {
606 summary: mem::take(&mut self.leaf_summary),
607 items: mem::take(&mut self.leaf_items),
608 item_summaries: mem::take(&mut self.leaf_item_summaries),
609 })),
610 cx,
611 );
612 }
613 fn push_item(&mut self, item: &T, summary: &T::Summary, cx: &<T::Summary as Summary>::Context) {
614 self.leaf_items.push(item.clone());
615 self.leaf_item_summaries.push(summary.clone());
616 Summary::add_summary(&mut self.leaf_summary, summary, cx);
617 }
618 fn push_tree(
619 &mut self,
620 tree: &SumTree<T>,
621 _: &T::Summary,
622 cx: &<T::Summary as Summary>::Context,
623 ) {
624 self.tree.push_tree(tree.clone(), cx);
625 }
626}
627
628impl<'a, T: Item, D> SeekAggregate<'a, T> for SummarySeekAggregate<D>
629where
630 D: Dimension<'a, T::Summary>,
631{
632 fn begin_leaf(&mut self) {}
633 fn end_leaf(&mut self, _: &<T::Summary as Summary>::Context) {}
634 fn push_item(&mut self, _: &T, summary: &'a T::Summary, cx: &<T::Summary as Summary>::Context) {
635 self.0.add_summary(summary, cx);
636 }
637 fn push_tree(
638 &mut self,
639 _: &SumTree<T>,
640 summary: &'a T::Summary,
641 cx: &<T::Summary as Summary>::Context,
642 ) {
643 self.0.add_summary(summary, cx);
644 }
645}