Remove type parameters from Cursor::seek_internal
Instead, use trait objects for the target dimension and aggregation
This commit is contained in:
parent
3719a9ee23
commit
24918b5cbc
1 changed files with 100 additions and 87 deletions
|
@ -1,6 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use std::{cmp::Ordering, sync::Arc};
|
use std::{cmp::Ordering, mem, sync::Arc};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct StackEntry<'a, T: Item, D> {
|
struct StackEntry<'a, T: Item, D> {
|
||||||
|
@ -324,7 +324,7 @@ where
|
||||||
Target: SeekTarget<'a, T::Summary, D>,
|
Target: SeekTarget<'a, T::Summary, D>,
|
||||||
{
|
{
|
||||||
self.reset();
|
self.reset();
|
||||||
self.seek_internal::<_, ()>(pos, bias, &mut SeekAggregate::None, cx)
|
self.seek_internal(pos, bias, &mut (), cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn seek_forward<Target>(
|
pub fn seek_forward<Target>(
|
||||||
|
@ -336,7 +336,7 @@ where
|
||||||
where
|
where
|
||||||
Target: SeekTarget<'a, T::Summary, D>,
|
Target: SeekTarget<'a, T::Summary, D>,
|
||||||
{
|
{
|
||||||
self.seek_internal::<_, ()>(pos, bias, &mut SeekAggregate::None, cx)
|
self.seek_internal(pos, bias, &mut (), cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slice<Target>(
|
pub fn slice<Target>(
|
||||||
|
@ -348,23 +348,18 @@ where
|
||||||
where
|
where
|
||||||
Target: SeekTarget<'a, T::Summary, D>,
|
Target: SeekTarget<'a, T::Summary, D>,
|
||||||
{
|
{
|
||||||
let mut slice = SeekAggregate::Slice(SumTree::new());
|
let mut slice = SliceSeekAggregate {
|
||||||
self.seek_internal::<_, ()>(end, bias, &mut slice, cx);
|
tree: SumTree::new(),
|
||||||
if let SeekAggregate::Slice(slice) = slice {
|
leaf_items: ArrayVec::new(),
|
||||||
slice
|
leaf_item_summaries: ArrayVec::new(),
|
||||||
} else {
|
leaf_summary: T::Summary::default(),
|
||||||
unreachable!()
|
};
|
||||||
}
|
self.seek_internal(end, bias, &mut slice, cx);
|
||||||
|
slice.tree
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn suffix(&mut self, cx: &<T::Summary as Summary>::Context) -> SumTree<T> {
|
pub fn suffix(&mut self, cx: &<T::Summary as Summary>::Context) -> SumTree<T> {
|
||||||
let mut slice = SeekAggregate::Slice(SumTree::new());
|
self.slice(&End::new(), Bias::Right, cx)
|
||||||
self.seek_internal::<_, ()>(&End::new(), Bias::Right, &mut slice, cx);
|
|
||||||
if let SeekAggregate::Slice(slice) = slice {
|
|
||||||
slice
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn summary<Target, Output>(
|
pub fn summary<Target, Output>(
|
||||||
|
@ -377,26 +372,18 @@ where
|
||||||
Target: SeekTarget<'a, T::Summary, D>,
|
Target: SeekTarget<'a, T::Summary, D>,
|
||||||
Output: Dimension<'a, T::Summary>,
|
Output: Dimension<'a, T::Summary>,
|
||||||
{
|
{
|
||||||
let mut summary = SeekAggregate::Summary(Output::default());
|
let mut summary = SummarySeekAggregate(Output::default());
|
||||||
self.seek_internal(end, bias, &mut summary, cx);
|
self.seek_internal(end, bias, &mut summary, cx);
|
||||||
if let SeekAggregate::Summary(summary) = summary {
|
summary.0
|
||||||
summary
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seek_internal<Target, Output>(
|
fn seek_internal(
|
||||||
&mut self,
|
&mut self,
|
||||||
target: &Target,
|
target: &dyn SeekTarget<'a, T::Summary, D>,
|
||||||
bias: Bias,
|
bias: Bias,
|
||||||
aggregate: &mut SeekAggregate<T, Output>,
|
aggregate: &mut dyn SeekAggregate<'a, T>,
|
||||||
cx: &<T::Summary as Summary>::Context,
|
cx: &<T::Summary as Summary>::Context,
|
||||||
) -> bool
|
) -> bool {
|
||||||
where
|
|
||||||
Target: SeekTarget<'a, T::Summary, D>,
|
|
||||||
Output: Dimension<'a, T::Summary>,
|
|
||||||
{
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
target.cmp(&self.position, cx) >= Ordering::Equal,
|
target.cmp(&self.position, cx) >= Ordering::Equal,
|
||||||
"cannot seek backward from {:?} to {:?}",
|
"cannot seek backward from {:?} to {:?}",
|
||||||
|
@ -437,15 +424,7 @@ where
|
||||||
|| (comparison == Ordering::Equal && bias == Bias::Right)
|
|| (comparison == Ordering::Equal && bias == Bias::Right)
|
||||||
{
|
{
|
||||||
self.position = child_end;
|
self.position = child_end;
|
||||||
match aggregate {
|
aggregate.push_tree(child_tree, child_summary, cx);
|
||||||
SeekAggregate::None => {}
|
|
||||||
SeekAggregate::Slice(slice) => {
|
|
||||||
slice.push_tree(child_tree.clone(), cx);
|
|
||||||
}
|
|
||||||
SeekAggregate::Summary(summary) => {
|
|
||||||
summary.add_summary(child_summary, cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.index += 1;
|
entry.index += 1;
|
||||||
entry.position = self.position.clone();
|
entry.position = self.position.clone();
|
||||||
} else {
|
} else {
|
||||||
|
@ -464,12 +443,7 @@ where
|
||||||
ref item_summaries,
|
ref item_summaries,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let mut slice_items = ArrayVec::<T, { 2 * TREE_BASE }>::new();
|
aggregate.begin_leaf();
|
||||||
let mut slice_item_summaries = ArrayVec::<T::Summary, { 2 * TREE_BASE }>::new();
|
|
||||||
let mut slice_items_summary = match aggregate {
|
|
||||||
SeekAggregate::Slice(_) => Some(T::Summary::default()),
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (item, item_summary) in items[entry.index..]
|
for (item, item_summary) in items[entry.index..]
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -483,49 +457,15 @@ where
|
||||||
|| (comparison == Ordering::Equal && bias == Bias::Right)
|
|| (comparison == Ordering::Equal && bias == Bias::Right)
|
||||||
{
|
{
|
||||||
self.position = child_end;
|
self.position = child_end;
|
||||||
match aggregate {
|
aggregate.push_item(item, item_summary, cx);
|
||||||
SeekAggregate::None => {}
|
|
||||||
SeekAggregate::Slice(_) => {
|
|
||||||
slice_items.push(item.clone());
|
|
||||||
slice_item_summaries.push(item_summary.clone());
|
|
||||||
<T::Summary as Summary>::add_summary(
|
|
||||||
slice_items_summary.as_mut().unwrap(),
|
|
||||||
item_summary,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
SeekAggregate::Summary(summary) => {
|
|
||||||
summary.add_summary(item_summary, cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.index += 1;
|
entry.index += 1;
|
||||||
} else {
|
} else {
|
||||||
if let SeekAggregate::Slice(slice) = aggregate {
|
aggregate.end_leaf(cx);
|
||||||
slice.push_tree(
|
|
||||||
SumTree(Arc::new(Node::Leaf {
|
|
||||||
summary: slice_items_summary.unwrap(),
|
|
||||||
items: slice_items,
|
|
||||||
item_summaries: slice_item_summaries,
|
|
||||||
})),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break 'outer;
|
break 'outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let SeekAggregate::Slice(slice) = aggregate {
|
aggregate.end_leaf(cx);
|
||||||
if !slice_items.is_empty() {
|
|
||||||
slice.push_tree(
|
|
||||||
SumTree(Arc::new(Node::Leaf {
|
|
||||||
summary: slice_items_summary.unwrap(),
|
|
||||||
items: slice_items,
|
|
||||||
item_summaries: slice_item_summaries,
|
|
||||||
})),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,8 +565,81 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SeekAggregate<T: Item, D> {
|
trait SeekAggregate<'a, T: Item> {
|
||||||
None,
|
fn begin_leaf(&mut self);
|
||||||
Slice(SumTree<T>),
|
fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context);
|
||||||
Summary(D),
|
fn push_item(
|
||||||
|
&mut self,
|
||||||
|
item: &'a T,
|
||||||
|
summary: &'a T::Summary,
|
||||||
|
cx: &<T::Summary as Summary>::Context,
|
||||||
|
);
|
||||||
|
fn push_tree(
|
||||||
|
&mut self,
|
||||||
|
tree: &'a SumTree<T>,
|
||||||
|
summary: &'a T::Summary,
|
||||||
|
cx: &<T::Summary as Summary>::Context,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SliceSeekAggregate<T: Item> {
|
||||||
|
tree: SumTree<T>,
|
||||||
|
leaf_items: ArrayVec<T, { 2 * TREE_BASE }>,
|
||||||
|
leaf_item_summaries: ArrayVec<T::Summary, { 2 * TREE_BASE }>,
|
||||||
|
leaf_summary: T::Summary,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SummarySeekAggregate<D>(D);
|
||||||
|
|
||||||
|
impl<'a, T: Item> SeekAggregate<'a, T> for () {
|
||||||
|
fn begin_leaf(&mut self) {}
|
||||||
|
fn end_leaf(&mut self, _: &<T::Summary as Summary>::Context) {}
|
||||||
|
fn push_item(&mut self, _: &T, _: &T::Summary, _: &<T::Summary as Summary>::Context) {}
|
||||||
|
fn push_tree(&mut self, _: &SumTree<T>, _: &T::Summary, _: &<T::Summary as Summary>::Context) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Item> SeekAggregate<'a, T> for SliceSeekAggregate<T> {
|
||||||
|
fn begin_leaf(&mut self) {}
|
||||||
|
fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context) {
|
||||||
|
self.tree.push_tree(
|
||||||
|
SumTree(Arc::new(Node::Leaf {
|
||||||
|
summary: mem::take(&mut self.leaf_summary),
|
||||||
|
items: mem::take(&mut self.leaf_items),
|
||||||
|
item_summaries: mem::take(&mut self.leaf_item_summaries),
|
||||||
|
})),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fn push_item(&mut self, item: &T, summary: &T::Summary, cx: &<T::Summary as Summary>::Context) {
|
||||||
|
self.leaf_items.push(item.clone());
|
||||||
|
self.leaf_item_summaries.push(summary.clone());
|
||||||
|
Summary::add_summary(&mut self.leaf_summary, summary, cx);
|
||||||
|
}
|
||||||
|
fn push_tree(
|
||||||
|
&mut self,
|
||||||
|
tree: &SumTree<T>,
|
||||||
|
_: &T::Summary,
|
||||||
|
cx: &<T::Summary as Summary>::Context,
|
||||||
|
) {
|
||||||
|
self.tree.push_tree(tree.clone(), cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Item, D> SeekAggregate<'a, T> for SummarySeekAggregate<D>
|
||||||
|
where
|
||||||
|
D: Dimension<'a, T::Summary>,
|
||||||
|
{
|
||||||
|
fn begin_leaf(&mut self) {}
|
||||||
|
fn end_leaf(&mut self, _: &<T::Summary as Summary>::Context) {}
|
||||||
|
fn push_item(&mut self, _: &T, summary: &'a T::Summary, cx: &<T::Summary as Summary>::Context) {
|
||||||
|
self.0.add_summary(summary, cx);
|
||||||
|
}
|
||||||
|
fn push_tree(
|
||||||
|
&mut self,
|
||||||
|
_: &SumTree<T>,
|
||||||
|
summary: &'a T::Summary,
|
||||||
|
cx: &<T::Summary as Summary>::Context,
|
||||||
|
) {
|
||||||
|
self.0.add_summary(summary, cx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue