use std::borrow::Borrow;
use std::cmp::Ordering;
use std::mem;
use std::ops::{Bound, RangeBounds};
use typenum::{Add1, Unsigned};
use crate::config::OrdChunkSize as NodeSize;
use crate::nodes::sized_chunk::Chunk;
use crate::util::{clone_ref, Ref};
use self::Insert::*;
use self::InsertAction::*;
const NODE_SIZE: usize = NodeSize::USIZE;
const MEDIAN: usize = (NODE_SIZE + 1) >> 1;
pub trait BTreeValue {
type Key;
fn ptr_eq(&self, other: &Self) -> bool;
fn search_key<BK>(slice: &[Self], key: &BK) -> Result<usize, usize>
where
BK: Ord + ?Sized,
Self: Sized,
Self::Key: Borrow<BK>;
fn search_value(slice: &[Self], value: &Self) -> Result<usize, usize>
where
Self: Sized;
fn cmp_keys<BK>(&self, other: &BK) -> Ordering
where
BK: Ord + ?Sized,
Self::Key: Borrow<BK>;
fn cmp_values(&self, other: &Self) -> Ordering;
}
pub struct Node<A> {
keys: Chunk<A, NodeSize>,
children: Chunk<Option<Ref<Node<A>>>, Add1<NodeSize>>,
}
pub enum Insert<A> {
Added,
Replaced(A),
Update(Node<A>),
Split(Node<A>, A, Node<A>),
}
enum InsertAction<A> {
AddedAction,
ReplacedAction(A),
InsertAt,
InsertSplit(Node<A>, A, Node<A>),
}
pub enum Remove<A> {
NoChange,
Removed(A),
Update(A, Node<A>),
}
enum RemoveAction {
DeleteAt(usize),
PullUp(usize, usize, usize),
Merge(usize),
StealFromLeft(usize),
StealFromRight(usize),
MergeFirst(usize),
ContinueDown(usize),
}
impl<A> Clone for Node<A>
where
A: Clone,
{
fn clone(&self) -> Self {
Node {
keys: self.keys.clone(),
children: self.children.clone(),
}
}
}
impl<A> Default for Node<A> {
fn default() -> Self {
Node {
keys: Chunk::new(),
children: Chunk::unit(None),
}
}
}
impl<A> Node<A> {
#[inline]
fn has_room(&self) -> bool {
self.keys.len() < NODE_SIZE
}
#[inline]
fn too_small(&self) -> bool {
self.keys.len() < MEDIAN
}
#[inline]
fn is_leaf(&self) -> bool {
self.children[0].is_none()
}
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn unit(value: A) -> Self {
Node {
keys: Chunk::unit(value),
children: Chunk::pair(None, None),
}
}
#[inline]
pub fn from_split(left: Node<A>, median: A, right: Node<A>) -> Self {
Node {
keys: Chunk::unit(median),
children: Chunk::pair(Some(Ref::from(left)), Some(Ref::from(right))),
}
}
pub fn min(&self) -> Option<&A> {
match self.children.first().unwrap() {
None => self.keys.first(),
Some(ref child) => child.min(),
}
}
pub fn max(&self) -> Option<&A> {
match self.children.last().unwrap() {
None => self.keys.last(),
Some(ref child) => child.max(),
}
}
}
impl<A: BTreeValue> Node<A> {
fn child_contains<BK>(&self, index: usize, key: &BK) -> bool
where
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
if let Some(Some(ref child)) = self.children.get(index) {
child.lookup(key).is_some()
} else {
false
}
}
pub fn lookup<BK>(&self, key: &BK) -> Option<&A>
where
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
if self.keys.is_empty() {
return None;
}
match A::search_key(&self.keys, key) {
Ok(index) => Some(&self.keys[index]),
Err(index) => match self.children[index] {
None => None,
Some(ref node) => node.lookup(key),
},
}
}
pub fn lookup_mut<BK>(&mut self, key: &BK) -> Option<&mut A>
where
A: Clone,
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
if self.keys.is_empty() {
return None;
}
match A::search_key(&self.keys, key) {
Ok(index) => Some(&mut self.keys[index]),
Err(index) => match self.children[index] {
None => None,
Some(ref mut child_ref) => {
let child = Ref::make_mut(child_ref);
child.lookup_mut(key)
}
},
}
}
pub fn path_first<'a, BK>(
&'a self,
mut path: Vec<(&'a Node<A>, usize)>,
) -> Vec<(&'a Node<A>, usize)>
where
A: 'a,
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
if self.keys.is_empty() {
return Vec::new();
}
match self.children[0] {
None => {
path.push((self, 0));
path
}
Some(ref node) => {
path.push((self, 0));
node.path_first(path)
}
}
}
pub fn path_last<'a, BK>(
&'a self,
mut path: Vec<(&'a Node<A>, usize)>,
) -> Vec<(&'a Node<A>, usize)>
where
A: 'a,
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
if self.keys.is_empty() {
return Vec::new();
}
let end = self.children.len() - 1;
match self.children[end] {
None => {
path.push((self, end - 1));
path
}
Some(ref node) => {
path.push((self, end));
node.path_last(path)
}
}
}
pub fn path_next<'a, BK>(
&'a self,
key: &BK,
mut path: Vec<(&'a Node<A>, usize)>,
) -> Vec<(&'a Node<A>, usize)>
where
A: 'a,
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
if self.keys.is_empty() {
return Vec::new();
}
match A::search_key(&self.keys, key) {
Ok(index) => {
path.push((self, index));
path
}
Err(index) => match self.children[index] {
None => match self.keys.get(index) {
Some(_) => {
path.push((self, index));
path
}
None => Vec::new(),
},
Some(ref node) => {
path.push((self, index));
node.path_next(key, path)
}
},
}
}
pub fn path_prev<'a, BK>(
&'a self,
key: &BK,
mut path: Vec<(&'a Node<A>, usize)>,
) -> Vec<(&'a Node<A>, usize)>
where
A: 'a,
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
if self.keys.is_empty() {
return Vec::new();
}
match A::search_key(&self.keys, key) {
Ok(index) => {
path.push((self, index));
path
}
Err(index) => match self.children[index] {
None if index == 0 => Vec::new(),
None => match self.keys.get(index - 1) {
Some(_) => {
path.push((self, index));
path
}
None => Vec::new(),
},
Some(ref node) => {
path.push((self, index));
node.path_prev(key, path)
}
},
}
}
fn split(
&mut self,
value: A,
ins_left: Option<Node<A>>,
ins_right: Option<Node<A>>,
) -> Insert<A> {
let left_child = ins_left.map(Ref::from);
let right_child = ins_right.map(Ref::from);
let index = A::search_value(&self.keys, &value).unwrap_err();
let mut left_keys;
let mut left_children;
let mut right_keys;
let mut right_children;
let median;
if index < MEDIAN {
self.children[index] = left_child;
left_keys = Chunk::from_front(&mut self.keys, index);
left_keys.push_back(value);
left_keys.drain_from_front(&mut self.keys, MEDIAN - index - 1);
left_children = Chunk::from_front(&mut self.children, index + 1);
left_children.push_back(right_child);
left_children.drain_from_front(&mut self.children, MEDIAN - index - 1);
median = self.keys.pop_front();
right_keys = Chunk::drain_from(&mut self.keys);
right_children = Chunk::drain_from(&mut self.children);
} else if index > MEDIAN {
self.children[index] = left_child;
left_keys = Chunk::from_front(&mut self.keys, MEDIAN);
left_children = Chunk::from_front(&mut self.children, MEDIAN + 1);
median = self.keys.pop_front();
right_keys = Chunk::from_front(&mut self.keys, index - MEDIAN - 1);
right_keys.push_back(value);
right_keys.append(&mut self.keys);
right_children = Chunk::from_front(&mut self.children, index - MEDIAN);
right_children.push_back(right_child);
right_children.append(&mut self.children);
} else {
left_keys = Chunk::from_front(&mut self.keys, MEDIAN);
left_children = Chunk::from_front(&mut self.children, MEDIAN);
left_children.push_back(left_child);
median = value;
right_keys = Chunk::drain_from(&mut self.keys);
right_children = Chunk::drain_from(&mut self.children);
right_children[0] = right_child;
}
debug_assert!(left_keys.len() == MEDIAN);
debug_assert!(left_children.len() == MEDIAN + 1);
debug_assert!(right_keys.len() == MEDIAN);
debug_assert!(right_children.len() == MEDIAN + 1);
Split(
Node {
keys: left_keys,
children: left_children,
},
median,
Node {
keys: right_keys,
children: right_children,
},
)
}
fn merge(middle: A, left: Node<A>, mut right: Node<A>) -> Node<A> {
let mut keys = left.keys;
keys.push_back(middle);
keys.append(&mut right.keys);
let mut children = left.children;
children.append(&mut right.children);
Node { keys, children }
}
fn pop_min(&mut self) -> (A, Option<Ref<Node<A>>>) {
let value = self.keys.pop_front();
let child = self.children.pop_front();
(value, child)
}
fn pop_max(&mut self) -> (A, Option<Ref<Node<A>>>) {
let value = self.keys.pop_back();
let child = self.children.pop_back();
(value, child)
}
fn push_min(&mut self, child: Option<Ref<Node<A>>>, value: A) {
self.keys.push_front(value);
self.children.push_front(child);
}
fn push_max(&mut self, child: Option<Ref<Node<A>>>, value: A) {
self.keys.push_back(value);
self.children.push_back(child);
}
pub fn insert(&mut self, value: A) -> Insert<A>
where
A: Clone,
{
if self.keys.is_empty() {
self.keys.push_back(value);
self.children.push_back(None);
return Insert::Added;
}
let (median, left, right) = match A::search_value(&self.keys, &value) {
Ok(index) => {
return Insert::Replaced(mem::replace(&mut self.keys[index], value));
}
Err(index) => {
let has_room = self.has_room();
let action = match self.children[index] {
None => InsertAt,
Some(ref mut child_ref) => {
let child = Ref::make_mut(child_ref);
match child.insert(value.clone()) {
Insert::Added => AddedAction,
Insert::Replaced(value) => ReplacedAction(value),
Insert::Update(_) => unreachable!(),
Insert::Split(left, median, right) => InsertSplit(left, median, right),
}
}
};
match action {
ReplacedAction(value) => return Insert::Replaced(value),
AddedAction => {
return Insert::Added;
}
InsertAt => {
if has_room {
self.keys.insert(index, value);
self.children.insert(index + 1, None);
return Insert::Added;
} else {
(value, None, None)
}
}
InsertSplit(left, median, right) => {
if has_room {
self.children[index] = Some(Ref::from(left));
self.keys.insert(index, median);
self.children.insert(index + 1, Some(Ref::from(right)));
return Insert::Added;
} else {
(median, Some(left), Some(right))
}
}
}
}
};
self.split(median, left, right)
}
pub fn remove<BK>(&mut self, key: &BK) -> Remove<A>
where
A: Clone,
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
let index = A::search_key(&self.keys, key);
self.remove_index(index, key)
}
fn remove_index<BK>(&mut self, index: Result<usize, usize>, key: &BK) -> Remove<A>
where
A: Clone,
BK: Ord + ?Sized,
A::Key: Borrow<BK>,
{
let action = match index {
Ok(index) => {
match (&self.children[index], &self.children[index + 1]) {
(&None, &None) => RemoveAction::DeleteAt(index),
(&Some(ref left), _) if !left.too_small() => {
if left.is_leaf() {
RemoveAction::PullUp(left.keys.len() - 1, index, index)
} else {
RemoveAction::StealFromLeft(index + 1)
}
}
(_, &Some(ref right)) if !right.too_small() => {
if right.is_leaf() {
RemoveAction::PullUp(0, index, index + 1)
} else {
RemoveAction::StealFromRight(index)
}
}
(&Some(_), &Some(_)) => RemoveAction::Merge(index),
_ => unreachable!(),
}
}
Err(index) => match self.children[index] {
None => return Remove::NoChange,
Some(ref child) if child.too_small() => {
let left = if index > 0 {
self.children.get(index - 1)
} else {
None
};
match (left, self.children.get(index + 1)) {
(Some(&Some(ref old_left)), _) if !old_left.too_small() => {
RemoveAction::StealFromLeft(index)
}
(_, Some(&Some(ref old_right))) if !old_right.too_small() => {
RemoveAction::StealFromRight(index)
}
(_, Some(&Some(_))) => RemoveAction::MergeFirst(index),
(Some(&Some(_)), _) => RemoveAction::MergeFirst(index - 1),
_ => unreachable!(),
}
}
Some(_) => RemoveAction::ContinueDown(index),
},
};
match action {
RemoveAction::DeleteAt(index) => {
let pair = self.keys.remove(index);
self.children.remove(index);
Remove::Removed(pair)
}
RemoveAction::PullUp(target_index, pull_to, child_index) => {
let children = &mut self.children;
let mut update = None;
let mut value;
if let Some(&mut Some(ref mut child_ref)) = children.get_mut(child_index) {
let child = Ref::make_mut(child_ref);
match child.remove_index(Ok(target_index), key) {
Remove::NoChange => unreachable!(),
Remove::Removed(pulled_value) => {
value = self.keys.set(pull_to, pulled_value);
}
Remove::Update(pulled_value, new_child) => {
value = self.keys.set(pull_to, pulled_value);
update = Some(new_child);
}
}
} else {
unreachable!()
}
if let Some(new_child) = update {
children[child_index] = Some(Ref::from(new_child));
}
Remove::Removed(value)
}
RemoveAction::Merge(index) => {
let left = self.children.remove(index).unwrap();
let right = mem::replace(&mut self.children[index], None).unwrap();
let value = self.keys.remove(index);
let mut merged_child = Node::merge(value, clone_ref(left), clone_ref(right));
let (removed, new_child) = match merged_child.remove(key) {
Remove::NoChange => unreachable!(),
Remove::Removed(removed) => (removed, merged_child),
Remove::Update(removed, updated_child) => (removed, updated_child),
};
if self.keys.is_empty() {
Remove::Update(removed, new_child)
} else {
self.children[index] = Some(Ref::from(new_child));
Remove::Removed(removed)
}
}
RemoveAction::StealFromLeft(index) => {
let mut update = None;
let mut out_value;
{
let mut children = self.children.as_mut_slice()[index - 1..=index]
.iter_mut()
.map(|n| {
if let Some(ref mut o) = *n {
o
} else {
unreachable!()
}
});
let left = Ref::make_mut(children.next().unwrap());
let child = Ref::make_mut(children.next().unwrap());
child.push_min(
left.children.last().unwrap().clone(),
self.keys[index - 1].clone(),
);
match child.remove(key) {
Remove::NoChange => {
child.pop_min();
return Remove::NoChange;
}
Remove::Removed(value) => {
let (left_value, _) = left.pop_max();
self.keys[index - 1] = left_value;
out_value = value;
}
Remove::Update(value, new_child) => {
let (left_value, _) = left.pop_max();
self.keys[index - 1] = left_value;
update = Some(new_child);
out_value = value;
}
}
}
if let Some(new_child) = update {
self.children[index] = Some(Ref::from(new_child));
}
Remove::Removed(out_value)
}
RemoveAction::StealFromRight(index) => {
let mut update = None;
let mut out_value;
{
let mut children = self.children.as_mut_slice()[index..index + 2]
.iter_mut()
.map(|n| {
if let Some(ref mut o) = *n {
o
} else {
unreachable!()
}
});
let child = Ref::make_mut(children.next().unwrap());
let right = Ref::make_mut(children.next().unwrap());
child.push_max(right.children[0].clone(), self.keys[index].clone());
match child.remove(key) {
Remove::NoChange => {
child.pop_max();
return Remove::NoChange;
}
Remove::Removed(value) => {
let (right_value, _) = right.pop_min();
self.keys[index] = right_value;
out_value = value;
}
Remove::Update(value, new_child) => {
let (right_value, _) = right.pop_min();
self.keys[index] = right_value;
update = Some(new_child);
out_value = value;
}
}
}
if let Some(new_child) = update {
self.children[index] = Some(Ref::from(new_child));
}
Remove::Removed(out_value)
}
RemoveAction::MergeFirst(index) => {
if self.keys[index].cmp_keys(key) != Ordering::Equal
&& !self.child_contains(index, key)
&& !self.child_contains(index + 1, key)
{
return Remove::NoChange;
}
let left = self.children.remove(index).unwrap();
let right = mem::replace(&mut self.children[index], None).unwrap();
let middle = self.keys.remove(index);
let mut merged = Node::merge(middle, clone_ref(left), clone_ref(right));
let mut update;
let mut out_value;
match merged.remove(key) {
Remove::NoChange => {
panic!("nodes::btree::Node::remove: caught an absent key too late while merging");
}
Remove::Removed(value) => {
if self.keys.is_empty() {
return Remove::Update(value, merged);
}
update = merged;
out_value = value;
}
Remove::Update(value, new_child) => {
if self.keys.is_empty() {
return Remove::Update(value, new_child);
}
update = new_child;
out_value = value;
}
}
self.children[index] = Some(Ref::from(update));
Remove::Removed(out_value)
}
RemoveAction::ContinueDown(index) => {
let mut update = None;
let mut out_value;
if let Some(&mut Some(ref mut child_ref)) = self.children.get_mut(index) {
let child = Ref::make_mut(child_ref);
match child.remove(key) {
Remove::NoChange => return Remove::NoChange,
Remove::Removed(value) => {
out_value = value;
}
Remove::Update(value, new_child) => {
update = Some(new_child);
out_value = value;
}
}
} else {
unreachable!()
}
if let Some(new_child) = update {
self.children[index] = Some(Ref::from(new_child));
}
Remove::Removed(out_value)
}
}
}
}
pub struct Iter<'a, A: 'a> {
fwd_path: Vec<(&'a Node<A>, usize)>,
back_path: Vec<(&'a Node<A>, usize)>,
pub(crate) remaining: usize,
}
impl<'a, A: 'a + BTreeValue> Iter<'a, A> {
pub fn new<R, BK>(root: &'a Node<A>, size: usize, range: R) -> Self
where
R: RangeBounds<BK>,
A::Key: Borrow<BK>,
BK: Ord + ?Sized,
{
let fwd_path = match range.start_bound() {
Bound::Included(key) => root.path_next(key, Vec::new()),
Bound::Excluded(key) => {
let mut path = root.path_next(key, Vec::new());
if let Some(value) = Self::get(&path) {
if value.cmp_keys(key) == Ordering::Equal {
Self::step_forward(&mut path);
}
}
path
}
Bound::Unbounded => root.path_first(Vec::new()),
};
let back_path = match range.end_bound() {
Bound::Included(key) => root.path_prev(key, Vec::new()),
Bound::Excluded(key) => {
let mut path = root.path_prev(key, Vec::new());
if let Some(value) = Self::get(&path) {
if value.cmp_keys(key) == Ordering::Equal {
Self::step_back(&mut path);
}
}
path
}
Bound::Unbounded => root.path_last(Vec::new()),
};
Iter {
fwd_path,
back_path,
remaining: size,
}
}
fn get(path: &[(&'a Node<A>, usize)]) -> Option<&'a A> {
match path.last() {
Some((node, index)) => Some(&node.keys[*index]),
None => None,
}
}
fn step_forward(path: &mut Vec<(&'a Node<A>, usize)>) -> Option<&'a A> {
match path.pop() {
Some((node, index)) => {
let index = index + 1;
match node.children[index] {
Some(ref child) => {
path.push((node, index));
path.push((child, 0));
let mut node = child;
while let Some(ref left_child) = node.children[0] {
path.push((left_child, 0));
node = left_child;
}
Some(&node.keys[0])
}
None => match node.keys.get(index) {
value @ Some(_) => {
path.push((node, index));
value
}
None => loop {
match path.pop() {
None => {
return None;
}
Some((node, index)) => {
if let value @ Some(_) = node.keys.get(index) {
path.push((node, index));
return value;
}
}
}
},
},
}
}
None => None,
}
}
fn step_back(path: &mut Vec<(&'a Node<A>, usize)>) -> Option<&'a A> {
match path.pop() {
Some((node, index)) => match node.children[index] {
Some(ref child) => {
path.push((node, index));
let mut end = child.keys.len() - 1;
path.push((child, end));
let mut node = child;
while let Some(ref right_child) = node.children[end + 1] {
end = right_child.keys.len() - 1;
path.push((right_child, end));
node = right_child;
}
Some(&node.keys[end])
}
None => {
if index == 0 {
loop {
match path.pop() {
None => {
return None;
}
Some((node, index)) => {
if index > 0 {
let index = index - 1;
path.push((node, index));
return Some(&node.keys[index]);
}
}
}
}
} else {
let index = index - 1;
path.push((node, index));
Some(&node.keys[index])
}
}
},
None => None,
}
}
}
impl<'a, A: 'a + BTreeValue> Iterator for Iter<'a, A> {
type Item = &'a A;
fn next(&mut self) -> Option<Self::Item> {
match Iter::get(&self.fwd_path) {
None => None,
Some(value) => match Iter::get(&self.back_path) {
Some(last_value) if value.cmp_values(last_value) == Ordering::Greater => None,
None => None,
Some(_) => {
Iter::step_forward(&mut self.fwd_path);
self.remaining -= 1;
Some(value)
}
},
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<'a, A: 'a + BTreeValue> DoubleEndedIterator for Iter<'a, A> {
fn next_back(&mut self) -> Option<Self::Item> {
match Iter::get(&self.back_path) {
None => None,
Some(value) => match Iter::get(&self.fwd_path) {
Some(last_value) if value.cmp_values(last_value) == Ordering::Less => None,
None => None,
Some(_) => {
Iter::step_back(&mut self.back_path);
self.remaining -= 1;
Some(value)
}
},
}
}
}
enum ConsumingIterItem<A> {
Consider(Node<A>),
Yield(A),
}
pub struct ConsumingIter<A> {
fwd_last: Option<A>,
fwd_stack: Vec<ConsumingIterItem<A>>,
back_last: Option<A>,
back_stack: Vec<ConsumingIterItem<A>>,
remaining: usize,
}
impl<A: Clone> ConsumingIter<A> {
pub fn new(root: &Node<A>, total: usize) -> Self {
ConsumingIter {
fwd_last: None,
fwd_stack: vec![ConsumingIterItem::Consider(root.clone())],
back_last: None,
back_stack: vec![ConsumingIterItem::Consider(root.clone())],
remaining: total,
}
}
fn push_node(stack: &mut Vec<ConsumingIterItem<A>>, maybe_node: Option<Ref<Node<A>>>) {
if let Some(node) = maybe_node {
stack.push(ConsumingIterItem::Consider(clone_ref(node)))
}
}
fn push(stack: &mut Vec<ConsumingIterItem<A>>, mut node: Node<A>) {
for _n in 0..node.keys.len() {
ConsumingIter::push_node(stack, node.children.pop_back());
stack.push(ConsumingIterItem::Yield(node.keys.pop_back()));
}
ConsumingIter::push_node(stack, node.children.pop_back());
}
fn push_fwd(&mut self, node: Node<A>) {
ConsumingIter::push(&mut self.fwd_stack, node)
}
fn push_node_back(&mut self, maybe_node: Option<Ref<Node<A>>>) {
if let Some(node) = maybe_node {
self.back_stack
.push(ConsumingIterItem::Consider(clone_ref(node)))
}
}
fn push_back(&mut self, mut node: Node<A>) {
for _i in 0..node.keys.len() {
self.push_node_back(node.children.pop_front());
self.back_stack
.push(ConsumingIterItem::Yield(node.keys.pop_front()));
}
self.push_node_back(node.children.pop_back());
}
}
impl<A> Iterator for ConsumingIter<A>
where
A: BTreeValue + Clone,
{
type Item = A;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.fwd_stack.pop() {
None => {
self.remaining = 0;
return None;
}
Some(ConsumingIterItem::Consider(node)) => self.push_fwd(node),
Some(ConsumingIterItem::Yield(value)) => {
if let Some(ref last) = self.back_last {
if value.cmp_values(last) != Ordering::Less {
self.fwd_stack.clear();
self.back_stack.clear();
self.remaining = 0;
return None;
}
}
self.remaining -= 1;
self.fwd_last = Some(value.clone());
return Some(value);
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<A> DoubleEndedIterator for ConsumingIter<A>
where
A: BTreeValue + Clone,
{
fn next_back(&mut self) -> Option<Self::Item> {
loop {
match self.back_stack.pop() {
None => {
self.remaining = 0;
return None;
}
Some(ConsumingIterItem::Consider(node)) => self.push_back(node),
Some(ConsumingIterItem::Yield(value)) => {
if let Some(ref last) = self.fwd_last {
if value.cmp_values(last) != Ordering::Greater {
self.fwd_stack.clear();
self.back_stack.clear();
self.remaining = 0;
return None;
}
}
self.remaining -= 1;
self.back_last = Some(value.clone());
return Some(value);
}
}
}
}
}
impl<A: BTreeValue + Clone> ExactSizeIterator for ConsumingIter<A> {}
pub struct DiffIter<'a, A: 'a> {
old_stack: Vec<IterItem<'a, A>>,
new_stack: Vec<IterItem<'a, A>>,
}
#[derive(PartialEq, Eq)]
pub enum DiffItem<'a, A: 'a> {
Add(&'a A),
Update { old: &'a A, new: &'a A },
Remove(&'a A),
}
enum IterItem<'a, A: 'a> {
Consider(&'a Node<A>),
Yield(&'a A),
}
impl<'a, A: 'a> DiffIter<'a, A> {
pub fn new(old: &'a Node<A>, new: &'a Node<A>) -> Self {
DiffIter {
old_stack: if old.keys.is_empty() {
Vec::new()
} else {
vec![IterItem::Consider(old)]
},
new_stack: if new.keys.is_empty() {
Vec::new()
} else {
vec![IterItem::Consider(new)]
},
}
}
fn push_node(stack: &mut Vec<IterItem<'a, A>>, maybe_node: &'a Option<Ref<Node<A>>>) {
if let Some(ref node) = *maybe_node {
stack.push(IterItem::Consider(&node))
}
}
fn push(stack: &mut Vec<IterItem<'a, A>>, node: &'a Node<A>) {
for n in 0..node.keys.len() {
let i = node.keys.len() - n;
Self::push_node(stack, &node.children[i]);
stack.push(IterItem::Yield(&node.keys[i - 1]));
}
Self::push_node(stack, &node.children[0]);
}
}
impl<'a, A> Iterator for DiffIter<'a, A>
where
A: 'a + BTreeValue + PartialEq,
{
type Item = DiffItem<'a, A>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match (self.old_stack.pop(), self.new_stack.pop()) {
(None, None) => return None,
(None, Some(new)) => match new {
IterItem::Consider(new) => Self::push(&mut self.new_stack, &new),
IterItem::Yield(new) => return Some(DiffItem::Add(new)),
},
(Some(old), None) => match old {
IterItem::Consider(old) => Self::push(&mut self.old_stack, &old),
IterItem::Yield(old) => return Some(DiffItem::Remove(old)),
},
(Some(old), Some(new)) => match (old, new) {
(IterItem::Consider(old), IterItem::Consider(new)) => {
match old.keys[0].cmp_values(&new.keys[0]) {
Ordering::Less => {
Self::push(&mut self.old_stack, &old);
self.new_stack.push(IterItem::Consider(new));
}
Ordering::Greater => {
self.old_stack.push(IterItem::Consider(old));
Self::push(&mut self.new_stack, &new);
}
Ordering::Equal => {
Self::push(&mut self.old_stack, &old);
Self::push(&mut self.new_stack, &new);
}
}
}
(IterItem::Consider(old), IterItem::Yield(new)) => {
Self::push(&mut self.old_stack, &old);
self.new_stack.push(IterItem::Yield(new));
}
(IterItem::Yield(old), IterItem::Consider(new)) => {
self.old_stack.push(IterItem::Yield(old));
Self::push(&mut self.new_stack, &new);
}
(IterItem::Yield(old), IterItem::Yield(new)) => match old.cmp_values(&new) {
Ordering::Less => {
self.new_stack.push(IterItem::Yield(new));
return Some(DiffItem::Remove(old));
}
Ordering::Equal => {
if old != new {
return Some(DiffItem::Update { old, new });
}
}
Ordering::Greater => {
self.old_stack.push(IterItem::Yield(old));
return Some(DiffItem::Add(new));
}
},
},
}
}
}
}