mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-02 11:06:14 +00:00
refactor: make bump optional in rle tree
This commit is contained in:
parent
ea2f1256b8
commit
24cd11f59e
7 changed files with 375 additions and 148 deletions
|
@ -1,9 +1,11 @@
|
|||
use std::{collections::HashMap, ptr::NonNull};
|
||||
|
||||
use self::node::{InternalNode, LeafNode, Node};
|
||||
use self::{
|
||||
arena::Arena,
|
||||
node::{InternalNode, LeafNode, Node},
|
||||
};
|
||||
use crate::Rle;
|
||||
pub(self) use bumpalo::collections::vec::Vec as BumpVec;
|
||||
use bumpalo::Bump;
|
||||
pub use cursor::{SafeCursor, SafeCursorMut, UnsafeCursor};
|
||||
use fxhash::FxHashMap;
|
||||
use num::FromPrimitive;
|
||||
|
@ -13,6 +15,7 @@ use smallvec::SmallVec;
|
|||
pub use tree_trait::Position;
|
||||
use tree_trait::RleTreeTrait;
|
||||
|
||||
mod arena;
|
||||
mod cursor;
|
||||
pub mod iter;
|
||||
pub mod node;
|
||||
|
@ -23,16 +26,19 @@ pub mod tree_trait;
|
|||
#[self_referencing]
|
||||
#[derive(Debug)]
|
||||
pub struct RleTree<T: Rle + 'static, A: RleTreeTrait<T> + 'static> {
|
||||
pub(crate) bump: Bump,
|
||||
pub(crate) bump: A::Arena,
|
||||
#[borrows(bump)]
|
||||
node: &'this mut Node<'this, T, A>,
|
||||
#[not_covariant]
|
||||
node: <A::Arena as arena::Arena>::Boxed<'this, Node<'this, T, A>>,
|
||||
}
|
||||
|
||||
impl<T: Rle + 'static, A: RleTreeTrait<T> + 'static> Default for RleTree<T, A> {
|
||||
fn default() -> Self {
|
||||
RleTreeBuilder {
|
||||
bump: Bump::new(),
|
||||
node_builder: |bump| bump.alloc(Node::Internal(InternalNode::new(bump, None))),
|
||||
bump: Default::default(),
|
||||
node_builder: |bump: &A::Arena| {
|
||||
bump.allocate(Node::Internal(InternalNode::new(bump, None)))
|
||||
},
|
||||
}
|
||||
.build()
|
||||
}
|
||||
|
@ -104,7 +110,7 @@ impl<T: Rle, A: RleTreeTrait<T>> RleTree<T, A> {
|
|||
return None;
|
||||
}
|
||||
|
||||
node = internal_node.children[result.child_index];
|
||||
node = &internal_node.children[result.child_index];
|
||||
index = result.offset;
|
||||
}
|
||||
Node::Leaf(leaf) => {
|
||||
|
@ -138,7 +144,7 @@ impl<T: Rle, A: RleTreeTrait<T>> RleTree<T, A> {
|
|||
return None;
|
||||
}
|
||||
|
||||
node = internal_node.children[result.child_index];
|
||||
node = &internal_node.children[result.child_index];
|
||||
index = result.offset;
|
||||
}
|
||||
Node::Leaf(leaf) => {
|
||||
|
|
189
crates/rle/src/rle_tree/arena.rs
Normal file
189
crates/rle/src/rle_tree/arena.rs
Normal file
|
@ -0,0 +1,189 @@
|
|||
use super::BumpVec;
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
ops::{Deref, DerefMut, Index, RangeBounds, IndexMut},
|
||||
};
|
||||
|
||||
use bumpalo::Bump;
|
||||
fn test() {
|
||||
let mut a = vec![1, 2];
|
||||
}
|
||||
|
||||
pub trait VecTrait<'v, T>:
|
||||
Index<usize, Output = T> + IndexMut<usize> + Deref<Target = [T]> + DerefMut + Debug
|
||||
{
|
||||
type Arena;
|
||||
type Drain<'a>: Iterator<Item = T>
|
||||
where
|
||||
Self:'a;
|
||||
|
||||
fn drain<'a, R>(&'a mut self, range: R) -> Self::Drain<'a>
|
||||
where
|
||||
R: RangeBounds<usize>;
|
||||
|
||||
fn push(&mut self, value: T);
|
||||
fn pop(&mut self) -> Option<T>;
|
||||
fn clear(&mut self);
|
||||
fn insert(&mut self, index: usize, value: T);
|
||||
fn with_capacity_in(capacity: usize, arena: &'v Self::Arena) -> Self;
|
||||
fn splice<R, I>(&mut self, range: R, replace_with: I)
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
I: IntoIterator<Item = T>;
|
||||
}
|
||||
|
||||
pub trait Arena: Debug + Default {
|
||||
type Boxed<'a, T>: Debug + Deref<Target = T> + DerefMut
|
||||
where
|
||||
Self: 'a,
|
||||
T: 'a + Debug;
|
||||
|
||||
type Vec<'v, T>: VecTrait<'v, T, Arena = Self>
|
||||
where
|
||||
Self: 'v,
|
||||
T: 'v + Debug;
|
||||
|
||||
fn allocate<'a, T>(&'a self, value: T) -> Self::Boxed<'a, T>
|
||||
where
|
||||
T: 'a + Debug;
|
||||
|
||||
fn allocated_bytes(&self) -> usize;
|
||||
}
|
||||
|
||||
impl<'bump, T: Debug + 'bump> VecTrait<'bump, T> for BumpVec<'bump, T> {
|
||||
type Drain<'a> = bumpalo::collections::vec::Drain<'a, 'bump, T>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
#[inline(always)]
|
||||
fn drain< R>(& mut self, range: R) -> Self::Drain<'_>
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
{
|
||||
// SAFETY: The lifetime of the returned iterator is bound to the lifetime of the arena.
|
||||
unsafe{ std::mem::transmute(self.drain(range))}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn push(&mut self, value: T) {
|
||||
self.push(value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pop(&mut self) -> Option<T> {
|
||||
self.pop()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn clear(&mut self) {
|
||||
self.clear()
|
||||
}
|
||||
|
||||
type Arena = Bump;
|
||||
|
||||
#[inline(always)]
|
||||
fn insert(&mut self, index: usize, value: T) {
|
||||
self.insert(index, value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn with_capacity_in(capacity: usize, arena: &'bump Self::Arena) -> BumpVec<'bump, T> {
|
||||
BumpVec::with_capacity_in(capacity, arena)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn splice<R, I>(&mut self, range: R, replace_with: I)
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
self.splice(range, replace_with);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'v, T: Debug + 'v> VecTrait<'v, T> for Vec<T> {
|
||||
type Drain<'a> = std::vec::Drain<'a, T>
|
||||
where
|
||||
Self: 'a,
|
||||
Self: 'v,
|
||||
T: 'a;
|
||||
|
||||
#[inline(always)]
|
||||
fn drain<'a, R>(&'a mut self, range: R) -> Self::Drain<'a>
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
{
|
||||
self.drain(range)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn push(&mut self, value: T) {
|
||||
self.push(value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pop(&mut self) -> Option<T> {
|
||||
self.pop()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn clear(&mut self) {
|
||||
self.clear()
|
||||
}
|
||||
|
||||
type Arena = Heap;
|
||||
|
||||
#[inline(always)]
|
||||
fn insert(&mut self, index: usize, value: T) {
|
||||
self.insert(index, value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn with_capacity_in(capacity: usize, _: &Self::Arena) -> Self {
|
||||
Vec::with_capacity(capacity)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn splice<R, I>(&mut self, range: R, replace_with: I)
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
self.splice(range, replace_with);
|
||||
}
|
||||
}
|
||||
|
||||
impl Arena for Bump {
|
||||
type Boxed<'a, T> = &'a mut T where T: 'a + Debug;
|
||||
type Vec<'a, T> = BumpVec<'a, T> where T: 'a + Debug;
|
||||
|
||||
fn allocate<'a, T>(&'a self, value: T) -> Self::Boxed<'a, T>
|
||||
where
|
||||
T: 'a + Debug,
|
||||
{
|
||||
self.alloc(value)
|
||||
}
|
||||
|
||||
fn allocated_bytes(&self) -> usize {
|
||||
Bump::allocated_bytes(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Heap;
|
||||
|
||||
impl Arena for Heap {
|
||||
type Boxed<'a, T> = Box<T> where T: 'a + Debug;
|
||||
type Vec<'a, T> = Vec<T> where T: 'a + Debug;
|
||||
|
||||
fn allocate<'a, T>(&'a self, value: T) -> Self::Boxed<'a, T>
|
||||
where
|
||||
T: 'a + Debug,
|
||||
{
|
||||
Box::new(value)
|
||||
}
|
||||
|
||||
fn allocated_bytes(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ use super::{node::LeafNode, tree_trait::Position};
|
|||
|
||||
/// when len > 0, it acts as a selection. When iterating the tree, the len should be the size of the element.
|
||||
#[derive(Debug)]
|
||||
pub struct UnsafeCursor<'tree, T: Rle, A: RleTreeTrait<T>> {
|
||||
pub struct UnsafeCursor<'tree, T: Rle, A: RleTreeTrait<T> + 'tree> {
|
||||
pub leaf: NonNull<LeafNode<'tree, T, A>>,
|
||||
pub index: usize,
|
||||
pub offset: usize,
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
use std::{
|
||||
fmt::Debug,
|
||||
marker::{PhantomData, PhantomPinned},
|
||||
ops::Deref,
|
||||
ptr::NonNull,
|
||||
};
|
||||
|
||||
use crate::Rle;
|
||||
use bumpalo::boxed::Box as BumpBox;
|
||||
|
||||
use super::{cursor::SafeCursor, tree_trait::RleTreeTrait, BumpVec};
|
||||
use bumpalo::Bump;
|
||||
use super::{
|
||||
arena::{Arena, VecTrait},
|
||||
cursor::SafeCursor,
|
||||
tree_trait::RleTreeTrait,
|
||||
};
|
||||
use enum_as_inner::EnumAsInner;
|
||||
mod internal_impl;
|
||||
mod leaf_impl;
|
||||
|
@ -21,10 +24,11 @@ pub enum Node<'a, T: Rle, A: RleTreeTrait<T>> {
|
|||
Leaf(LeafNode<'a, T, A>),
|
||||
}
|
||||
|
||||
pub struct InternalNode<'a, T: Rle, A: RleTreeTrait<T>> {
|
||||
bump: &'a Bump,
|
||||
pub struct InternalNode<'a, T: Rle + 'a, A: RleTreeTrait<T> + 'a> {
|
||||
bump: &'a A::Arena,
|
||||
pub(crate) parent: Option<NonNull<InternalNode<'a, T, A>>>,
|
||||
pub(super) children: BumpVec<'a, &'a mut Node<'a, T, A>>,
|
||||
pub(super) children:
|
||||
<A::Arena as Arena>::Vec<'a, <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>>,
|
||||
pub cache: A::InternalCache,
|
||||
_pin: PhantomPinned,
|
||||
_a: PhantomData<A>,
|
||||
|
@ -33,10 +37,10 @@ pub struct InternalNode<'a, T: Rle, A: RleTreeTrait<T>> {
|
|||
// TODO: remove bump field
|
||||
// TODO: remove parent field?
|
||||
// TODO: only one child?
|
||||
pub struct LeafNode<'a, T: Rle, A: RleTreeTrait<T>> {
|
||||
bump: &'a Bump,
|
||||
pub struct LeafNode<'a, T: Rle + 'a, A: RleTreeTrait<T>> {
|
||||
bump: &'a A::Arena,
|
||||
pub(crate) parent: NonNull<InternalNode<'a, T, A>>,
|
||||
pub(crate) children: BumpVec<'a, BumpBox<'a, T>>,
|
||||
pub(crate) children: <A::Arena as Arena>::Vec<'a, <A::Arena as Arena>::Boxed<'a, T>>,
|
||||
pub(crate) prev: Option<NonNull<LeafNode<'a, T, A>>>,
|
||||
pub(crate) next: Option<NonNull<LeafNode<'a, T, A>>>,
|
||||
pub cache: A::LeafCache,
|
||||
|
@ -52,13 +56,16 @@ pub(crate) enum Either {
|
|||
|
||||
impl<'a, T: Rle, A: RleTreeTrait<T>> Node<'a, T, A> {
|
||||
#[inline]
|
||||
fn _new_internal(bump: &'a Bump, parent: Option<NonNull<InternalNode<'a, T, A>>>) -> Self {
|
||||
fn _new_internal(bump: &'a A::Arena, parent: Option<NonNull<InternalNode<'a, T, A>>>) -> Self {
|
||||
Self::Internal(InternalNode::new(bump, parent))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new_leaf(bump: &'a Bump, parent: NonNull<InternalNode<'a, T, A>>) -> &'a mut Self {
|
||||
bump.alloc(Self::Leaf(LeafNode::new(bump, parent)))
|
||||
fn new_leaf(
|
||||
bump: &'a A::Arena,
|
||||
parent: NonNull<InternalNode<'a, T, A>>,
|
||||
) -> <A::Arena as Arena>::Boxed<'a, Self> {
|
||||
bump.allocate(Self::Leaf(LeafNode::new(bump, parent)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -126,7 +133,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> Node<'a, T, A> {
|
|||
let ans = parent
|
||||
.children
|
||||
.iter()
|
||||
.position(|child| match (child, self) {
|
||||
.position(|child| match (child.deref(), self) {
|
||||
(Node::Internal(a), Node::Internal(b)) => std::ptr::eq(a, b),
|
||||
(Node::Leaf(a), Node::Leaf(b)) => std::ptr::eq(a, b),
|
||||
_ => false,
|
||||
|
@ -147,9 +154,9 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> Node<'a, T, A> {
|
|||
let index = self.get_self_index()?;
|
||||
let parent = self.parent()?;
|
||||
if index > 0 {
|
||||
Some((parent.children[index - 1], Either::Left))
|
||||
Some((&parent.children[index - 1], Either::Left))
|
||||
} else if index + 1 < parent.children.len() {
|
||||
Some((parent.children[index + 1], Either::Right))
|
||||
Some((&parent.children[index + 1], Either::Right))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -175,7 +182,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> Node<'a, T, A> {
|
|||
Node::Internal(sibling) => {
|
||||
let self_node = self.as_internal_mut().unwrap();
|
||||
let ptr = NonNull::new(&mut *sibling).unwrap();
|
||||
for child in self_node.children.drain(..) {
|
||||
for mut child in self_node.children.drain(..) {
|
||||
child.set_parent(ptr);
|
||||
sibling.children.push(child);
|
||||
}
|
||||
|
@ -195,7 +202,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> Node<'a, T, A> {
|
|||
let ptr = NonNull::new(&mut *sibling).unwrap();
|
||||
sibling.children.splice(
|
||||
0..0,
|
||||
self_node.children.drain(0..).map(|x| {
|
||||
self_node.children.drain(0..).map(|mut x| {
|
||||
x.set_parent(ptr);
|
||||
x
|
||||
}),
|
||||
|
@ -232,10 +239,11 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> Node<'a, T, A> {
|
|||
Node::Internal(sibling) => {
|
||||
let self_node = self.as_internal_mut().unwrap();
|
||||
let self_ptr = NonNull::new(&mut *self_node).unwrap();
|
||||
let sibling_drain = sibling.children.drain(A::MIN_CHILDREN_NUM..).map(|x| {
|
||||
x.set_parent(self_ptr);
|
||||
x
|
||||
});
|
||||
let sibling_drain =
|
||||
sibling.children.drain(A::MIN_CHILDREN_NUM..).map(|mut x| {
|
||||
x.set_parent(self_ptr);
|
||||
x
|
||||
});
|
||||
self_node.children.splice(0..0, sibling_drain);
|
||||
}
|
||||
Node::Leaf(sibling) => {
|
||||
|
@ -260,7 +268,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> Node<'a, T, A> {
|
|||
sibling
|
||||
.children
|
||||
.drain(0..sibling_len - A::MIN_CHILDREN_NUM)
|
||||
.map(|x| {
|
||||
.map(|mut x| {
|
||||
x.set_parent(self_ptr);
|
||||
x
|
||||
}),
|
||||
|
@ -319,7 +327,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> Node<'a, T, A> {
|
|||
f(self);
|
||||
match self {
|
||||
Node::Internal(node) => {
|
||||
for child in &node.children {
|
||||
for child in node.children.deref() {
|
||||
child.recursive_visit_all(f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::{
|
||||
collections::{BinaryHeap, HashSet},
|
||||
fmt::{Debug, Error, Formatter},
|
||||
ops::DerefMut,
|
||||
};
|
||||
|
||||
use fxhash::FxHashSet;
|
||||
|
@ -8,6 +9,7 @@ use smallvec::SmallVec;
|
|||
|
||||
use crate::{
|
||||
rle_tree::{
|
||||
arena::VecTrait,
|
||||
node::utils::distribute,
|
||||
tree_trait::{FindPosResult, Position},
|
||||
},
|
||||
|
@ -17,11 +19,11 @@ use crate::{
|
|||
use super::*;
|
||||
|
||||
impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
||||
pub fn new(bump: &'a Bump, parent: Option<NonNull<Self>>) -> Self {
|
||||
pub fn new(bump: &'a A::Arena, parent: Option<NonNull<Self>>) -> Self {
|
||||
Self {
|
||||
bump,
|
||||
parent,
|
||||
children: BumpVec::with_capacity_in(A::MAX_CHILDREN_NUM, bump),
|
||||
children: <A::Arena as Arena>::Vec::with_capacity_in(A::MAX_CHILDREN_NUM, bump),
|
||||
cache: Default::default(),
|
||||
_pin: PhantomPinned,
|
||||
_a: PhantomData,
|
||||
|
@ -30,10 +32,10 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
|
||||
/// return result need to update cache
|
||||
#[inline]
|
||||
fn _split(&mut self) -> &'a mut Node<'a, T, A> {
|
||||
let ans = self
|
||||
fn _split(&mut self) -> <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>> {
|
||||
let mut ans = self
|
||||
.bump
|
||||
.alloc(Node::Internal(Self::new(self.bump, self.parent)));
|
||||
.allocate(Node::Internal(Self::new(self.bump, self.parent)));
|
||||
let inner = ans.as_internal_mut().unwrap();
|
||||
self._balance(inner);
|
||||
ans
|
||||
|
@ -44,7 +46,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
fn _balance(&mut self, other: &mut Self) {
|
||||
let keep_num = (self.children.len() + other.children.len()) / 2;
|
||||
debug_assert!(keep_num >= A::MIN_CHILDREN_NUM);
|
||||
for child in self.children.drain(keep_num..) {
|
||||
for mut child in self.children.drain(keep_num..) {
|
||||
child.set_parent(other.into());
|
||||
other.children.push(child);
|
||||
}
|
||||
|
@ -54,7 +56,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn children(&self) -> &[&'a mut Node<'a, T, A>] {
|
||||
pub fn children(&self) -> &[<A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>] {
|
||||
&self.children
|
||||
}
|
||||
|
||||
|
@ -62,7 +64,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
pub(crate) fn _check_child_parent(&self) {
|
||||
for child in self.children.iter() {
|
||||
child.get_self_index().unwrap();
|
||||
match child {
|
||||
match child.deref() {
|
||||
Node::Internal(node) => {
|
||||
assert!(std::ptr::eq(node.parent.unwrap().as_ptr(), self));
|
||||
node._check_child_parent();
|
||||
|
@ -79,7 +81,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
|
||||
self.check_children_parent_link();
|
||||
for child in self.children.iter_mut() {
|
||||
match child {
|
||||
match child.deref_mut() {
|
||||
Node::Internal(node) => {
|
||||
node.check();
|
||||
}
|
||||
|
@ -130,7 +132,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
fn check_children_parent_link(&mut self) {
|
||||
let self_ptr = self as *const _;
|
||||
for child in self.children.iter_mut() {
|
||||
match child {
|
||||
match child.deref_mut() {
|
||||
Node::Internal(node) => {
|
||||
assert!(std::ptr::eq(node.parent.unwrap().as_ptr(), self_ptr));
|
||||
}
|
||||
|
@ -149,7 +151,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
visited: &mut SmallVec<[(usize, NonNull<Node<'a, T, A>>); 8]>,
|
||||
depth: usize,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'a mut Node<'a, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
|
@ -163,17 +165,15 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
to.map_or((self.children.len(), None), |x| self._delete_end(x));
|
||||
let deleted_len = direct_delete_end as isize - direct_delete_start as isize;
|
||||
// TODO: maybe we can simplify this insertions logic
|
||||
let mut insertions: SmallVec<[(usize, &mut Node<T, A>); 2]> = smallvec::smallvec![];
|
||||
let mut insertions: SmallVec<[(usize, <A::Arena as Arena>::Boxed<'a, Node<T, A>>); 2]> =
|
||||
smallvec::smallvec![];
|
||||
{
|
||||
// handle removing at the end point
|
||||
let mut handled = false;
|
||||
if let (Some(del_from), Some(del_to)) = (to_del_start_offset, to_del_end_offset) {
|
||||
if direct_delete_start - 1 == direct_delete_end {
|
||||
visited.push((
|
||||
depth,
|
||||
NonNull::new(&mut *self.children[direct_delete_end]).unwrap(),
|
||||
));
|
||||
match &mut self.children[direct_delete_end] {
|
||||
visited.push((depth, self.children[direct_delete_end].deref().into()));
|
||||
match self.children[direct_delete_end].deref_mut() {
|
||||
Node::Internal(node) => {
|
||||
if let Err(new) = node._delete(
|
||||
Some(del_from),
|
||||
|
@ -201,7 +201,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
depth,
|
||||
NonNull::new(&mut *self.children[direct_delete_start - 1]).unwrap(),
|
||||
));
|
||||
match &mut self.children[direct_delete_start - 1] {
|
||||
match self.children[direct_delete_start - 1].deref_mut() {
|
||||
Node::Internal(node) => {
|
||||
if let Err(new) =
|
||||
node._delete(Some(del_from), None, visited, depth + 1, notify)
|
||||
|
@ -223,7 +223,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
depth,
|
||||
NonNull::new(&mut *self.children[direct_delete_end]).unwrap(),
|
||||
));
|
||||
match &mut self.children[direct_delete_end] {
|
||||
match self.children[direct_delete_end].deref_mut() {
|
||||
Node::Internal(node) => {
|
||||
if let Err(new) =
|
||||
node._delete(None, Some(del_to), visited, depth + 1, notify)
|
||||
|
@ -271,18 +271,22 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
|
||||
pub(crate) fn apply_updates(
|
||||
&mut self,
|
||||
mut updates: Vec<(usize, Vec<&'a mut Node<'a, T, A>>)>,
|
||||
) -> Result<(), Vec<&'a mut Node<'a, T, A>>> {
|
||||
mut updates: Vec<(usize, Vec<<A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>>)>,
|
||||
) -> Result<(), Vec<<A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>>> {
|
||||
if updates.is_empty() {
|
||||
A::update_cache_internal(self);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
updates.sort_by_key(|x| x.0);
|
||||
let mut new_children: Vec<&'a mut Node<'a, T, A>> = Vec::with_capacity(A::MAX_CHILDREN_NUM);
|
||||
let mut new_children: Vec<<A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>> =
|
||||
Vec::with_capacity(A::MAX_CHILDREN_NUM);
|
||||
let mut self_children = std::mem::replace(
|
||||
&mut self.children,
|
||||
BumpVec::with_capacity_in(A::MAX_CHILDREN_NUM, self.bump),
|
||||
<<A::Arena as Arena>::Vec<'_, _> as VecTrait<_>>::with_capacity_in(
|
||||
A::MAX_CHILDREN_NUM,
|
||||
self.bump,
|
||||
),
|
||||
);
|
||||
let mut saved_end = 0;
|
||||
for (index, replace) in updates {
|
||||
|
@ -303,7 +307,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
|
||||
let self_ptr: NonNull<_> = self.into();
|
||||
let result = if new_children.len() <= A::MAX_CHILDREN_NUM {
|
||||
for child in new_children {
|
||||
for mut child in new_children {
|
||||
child.set_parent(self_ptr);
|
||||
self.children.push(child);
|
||||
}
|
||||
|
@ -314,7 +318,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
let children_nums =
|
||||
distribute(new_children.len(), A::MIN_CHILDREN_NUM, A::MAX_CHILDREN_NUM);
|
||||
let mut index = 0;
|
||||
for child in new_children.drain(0..children_nums[index]) {
|
||||
for mut child in new_children.drain(0..children_nums[index]) {
|
||||
child.set_parent(self_ptr);
|
||||
self.children.push(child);
|
||||
}
|
||||
|
@ -323,11 +327,11 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
A::update_cache_internal(self);
|
||||
let mut ans_vec = Vec::new();
|
||||
while !new_children.is_empty() {
|
||||
let new_internal_node = self
|
||||
let mut new_internal_node = self
|
||||
.bump
|
||||
.alloc(Node::Internal(InternalNode::new(self.bump, self.parent)));
|
||||
.allocate(Node::Internal(InternalNode::new(self.bump, self.parent)));
|
||||
let new_internal = new_internal_node.as_internal_mut().unwrap();
|
||||
for child in new_children.drain(..children_nums[index]) {
|
||||
for mut child in new_children.drain(..children_nums[index]) {
|
||||
child.set_parent(new_internal.into());
|
||||
new_internal.children.push(child);
|
||||
}
|
||||
|
@ -345,7 +349,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
let new_vec = result.unwrap_err();
|
||||
{
|
||||
// create level
|
||||
let origin_root = self.bump.alloc(Node::Internal(InternalNode::new(
|
||||
let mut origin_root = self.bump.allocate(Node::Internal(InternalNode::new(
|
||||
self.bump,
|
||||
Some(self.into()),
|
||||
)));
|
||||
|
@ -361,7 +365,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
}
|
||||
|
||||
let ptr = self.into();
|
||||
for new_node in new_vec {
|
||||
for mut new_node in new_vec {
|
||||
new_node.set_parent(ptr);
|
||||
self.children.push(new_node);
|
||||
}
|
||||
|
@ -417,7 +421,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
index: A::Int,
|
||||
value: T,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'a mut Node<'a, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
|
@ -426,7 +430,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
A::update_cache_internal(self);
|
||||
Ok(())
|
||||
}
|
||||
Err(new) => {
|
||||
Err(mut new) => {
|
||||
A::update_cache_internal(self);
|
||||
A::update_cache_internal(new.as_internal_mut().unwrap());
|
||||
if self.is_root() {
|
||||
|
@ -440,11 +444,11 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
}
|
||||
|
||||
/// root node function. assume self and new's caches are up-to-date
|
||||
fn _create_level(&mut self, new: &'a mut Node<'a, T, A>) {
|
||||
fn _create_level(&mut self, mut new: <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>) {
|
||||
debug_assert!(self.is_root());
|
||||
let left = self
|
||||
let mut left = self
|
||||
.bump
|
||||
.alloc(Node::Internal(InternalNode::new(self.bump, None)));
|
||||
.allocate(Node::Internal(InternalNode::new(self.bump, None)));
|
||||
let left_inner = left.as_internal_mut().unwrap();
|
||||
std::mem::swap(left_inner, self);
|
||||
let left_ptr = left_inner.into();
|
||||
|
@ -464,7 +468,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
index: A::Int,
|
||||
value: T,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'a mut Node<'a, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
|
@ -480,7 +484,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
..
|
||||
} = A::find_pos_internal(self, index);
|
||||
let child = &mut self.children[child_index];
|
||||
let new = match child {
|
||||
let new = match child.deref_mut() {
|
||||
Node::Internal(child) => child.insert(relative_idx, value, notify),
|
||||
Node::Leaf(child) => child.insert(relative_idx, value, notify),
|
||||
};
|
||||
|
@ -495,15 +499,15 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
pub(crate) fn insert_at_pos(
|
||||
&mut self,
|
||||
index: usize,
|
||||
value: &'a mut Node<'a, T, A>,
|
||||
) -> Result<(), &'a mut Node<'a, T, A>> {
|
||||
value: <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>,
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>> {
|
||||
let result = self._insert_with_split(index, value);
|
||||
match result {
|
||||
Ok(_) => {
|
||||
A::update_cache_internal(self);
|
||||
Ok(())
|
||||
}
|
||||
Err(new) => {
|
||||
Err(mut new) => {
|
||||
A::update_cache_internal(self);
|
||||
A::update_cache_internal(new.as_internal_mut().unwrap());
|
||||
if self.is_root() {
|
||||
|
@ -531,7 +535,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
Ok(_) => {
|
||||
A::update_cache_internal(self);
|
||||
}
|
||||
Err(new) => {
|
||||
Err(mut new) => {
|
||||
A::update_cache_internal(self);
|
||||
A::update_cache_internal(new.as_internal_mut().unwrap());
|
||||
self._create_level(new);
|
||||
|
@ -618,7 +622,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
fn _root_shrink_levels_if_one_child(&mut self) -> FxHashSet<*const InternalNode<'a, T, A>> {
|
||||
let mut ans: HashSet<_, _> = FxHashSet::default();
|
||||
while self.children.len() == 1 && self.children[0].as_internal().is_some() {
|
||||
let child = self.children.pop().unwrap();
|
||||
let mut child = self.children.pop().unwrap();
|
||||
let child_ptr = child.as_internal_mut().unwrap();
|
||||
std::mem::swap(&mut *child_ptr, self);
|
||||
self.parent = None;
|
||||
|
@ -644,10 +648,10 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
fn _insert_with_split(
|
||||
&mut self,
|
||||
child_index: usize,
|
||||
new: &'a mut Node<'a, T, A>,
|
||||
) -> Result<(), &'a mut Node<'a, T, A>> {
|
||||
mut new: <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>,
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>> {
|
||||
if self.children.len() == A::MAX_CHILDREN_NUM {
|
||||
let ans = self._split();
|
||||
let mut ans = self._split();
|
||||
if child_index < self.children.len() {
|
||||
new.set_parent(self.into());
|
||||
self.children.insert(child_index, new);
|
||||
|
|
|
@ -2,6 +2,7 @@ use smallvec::SmallVec;
|
|||
|
||||
use crate::{
|
||||
rle_tree::{
|
||||
arena::VecTrait,
|
||||
cursor::SafeCursorMut,
|
||||
tree_trait::{FindPosResult, Position},
|
||||
},
|
||||
|
@ -13,11 +14,14 @@ use super::{utils::distribute, *};
|
|||
|
||||
impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
||||
#[inline]
|
||||
pub fn new(bump: &'bump Bump, parent: NonNull<InternalNode<'bump, T, A>>) -> Self {
|
||||
pub fn new(bump: &'bump A::Arena, parent: NonNull<InternalNode<'bump, T, A>>) -> Self {
|
||||
Self {
|
||||
bump,
|
||||
parent,
|
||||
children: BumpVec::with_capacity_in(A::MAX_CHILDREN_NUM, bump),
|
||||
children: <<A::Arena as Arena>::Vec<'bump, _> as VecTrait<_>>::with_capacity_in(
|
||||
A::MAX_CHILDREN_NUM,
|
||||
bump,
|
||||
),
|
||||
prev: None,
|
||||
next: None,
|
||||
cache: Default::default(),
|
||||
|
@ -27,13 +31,13 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn _split<F>(&mut self, notify: &mut F) -> &'bump mut Node<'bump, T, A>
|
||||
fn _split<F>(&mut self, notify: &mut F) -> <A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
let ans = self
|
||||
let mut ans = self
|
||||
.bump
|
||||
.alloc(Node::Leaf(Self::new(self.bump, self.parent)));
|
||||
.allocate(Node::Leaf(Self::new(self.bump, self.parent)));
|
||||
let ans_inner = ans.as_leaf_mut().unwrap();
|
||||
let ans_ptr = ans_inner as _;
|
||||
for child in self
|
||||
|
@ -80,7 +84,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
&mut self,
|
||||
value: T,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'bump mut Node<'bump, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
|
@ -96,7 +100,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
}
|
||||
|
||||
if self.children.len() == A::MAX_CHILDREN_NUM {
|
||||
let ans = self._split(notify);
|
||||
let mut ans = self._split(notify);
|
||||
let inner = ans.as_leaf_mut().unwrap();
|
||||
inner.push_child(value, notify).unwrap();
|
||||
A::update_cache_leaf(self);
|
||||
|
@ -104,7 +108,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
return Err(ans);
|
||||
}
|
||||
|
||||
self.children.push(BumpBox::new_in(value, self.bump));
|
||||
self.children.push(self.bump.allocate(value));
|
||||
notify(&self.children[self.children.len() - 1], self_ptr);
|
||||
A::update_cache_leaf(self);
|
||||
Ok(())
|
||||
|
@ -185,14 +189,14 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
raw_index: A::Int,
|
||||
value: T,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'bump mut Node<'bump, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
let result = {
|
||||
if self.children.is_empty() {
|
||||
notify(&value, self);
|
||||
self.children.push(BumpBox::new_in(value, self.bump));
|
||||
self.children.push(self.bump.allocate(value));
|
||||
Ok(())
|
||||
} else {
|
||||
let FindPosResult {
|
||||
|
@ -214,14 +218,14 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
offset: usize,
|
||||
value: T,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'bump mut Node<'bump, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
let result = {
|
||||
if self.children.is_empty() {
|
||||
notify(&value, self);
|
||||
self.children.push(BumpBox::new_in(value, self.bump));
|
||||
self.children.push(self.bump.allocate(value));
|
||||
Ok(())
|
||||
} else {
|
||||
self._insert_at_pos(pos, child_index, offset, value, notify)
|
||||
|
@ -239,7 +243,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
len: usize,
|
||||
update_fn: U,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'bump mut Node<'bump, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
U: FnOnce(&mut T),
|
||||
|
@ -272,7 +276,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
update_fn(&mut target);
|
||||
|
||||
if let Some(left) = left {
|
||||
self.children[child_index] = BumpBox::new_in(left, self.bump);
|
||||
self.children[child_index] = self.bump.allocate(left);
|
||||
let left = &mut self.children[child_index];
|
||||
if left.is_mergable(&target, &()) {
|
||||
left.merge(&target, &());
|
||||
|
@ -299,7 +303,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
} else {
|
||||
let result =
|
||||
self.insert_at_pos(Position::Start, child_index + 1, 0, target, notify);
|
||||
if let Err(new) = result {
|
||||
if let Err(mut new) = result {
|
||||
if self.children.len() >= child_index + 2 {
|
||||
// insert one element should not cause Err
|
||||
self.insert_at_pos(Position::Start, child_index + 2, 0, right, notify)
|
||||
|
@ -328,7 +332,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
return self.insert_at_pos(pos, child_index + 1, offset, target, notify);
|
||||
}
|
||||
} else {
|
||||
self.children[child_index] = BumpBox::new_in(target, self.bump);
|
||||
self.children[child_index] = self.bump.allocate(target);
|
||||
if let Some(right) = right {
|
||||
self.insert_at_pos(Position::Start, child_index + 1, 0, right, notify)
|
||||
} else {
|
||||
|
@ -436,7 +440,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
&mut self,
|
||||
mut updates: Vec<(usize, SmallVec<[T; 2]>)>,
|
||||
notify: &mut F,
|
||||
) -> Result<(), Vec<&'bump mut Node<'bump, T, A>>>
|
||||
) -> Result<(), Vec<<A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
|
@ -458,8 +462,14 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
}
|
||||
}
|
||||
|
||||
let mut new_children: Vec<BumpBox<T>> = Vec::new();
|
||||
let mut self_children = std::mem::replace(&mut self.children, BumpVec::new_in(self.bump));
|
||||
let mut new_children: Vec<_> = Vec::new();
|
||||
let mut self_children = std::mem::replace(
|
||||
&mut self.children,
|
||||
<<A::Arena as Arena>::Vec<'bump, _> as VecTrait<_>>::with_capacity_in(
|
||||
A::MAX_CHILDREN_NUM,
|
||||
self.bump,
|
||||
),
|
||||
);
|
||||
let mut last_end = 0;
|
||||
// append element to the new_children list
|
||||
for (index, replace) in updates {
|
||||
|
@ -478,7 +488,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
}
|
||||
}
|
||||
if !merged {
|
||||
new_children.push(BumpBox::new_in(element, self.bump));
|
||||
new_children.push(self.bump.allocate(element));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,9 +520,9 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
A::update_cache_leaf(self);
|
||||
let mut leaf_vec = Vec::new();
|
||||
while !new_children.is_empty() {
|
||||
let new_leaf_node = self
|
||||
let mut new_leaf_node = self
|
||||
.bump
|
||||
.alloc(Node::Leaf(LeafNode::new(self.bump, self.parent)));
|
||||
.allocate(Node::Leaf(LeafNode::new(self.bump, self.parent)));
|
||||
let new_leaf = new_leaf_node.as_leaf_mut().unwrap();
|
||||
for child in new_children.drain(..children_nums[index]) {
|
||||
notify(&child, new_leaf);
|
||||
|
@ -539,14 +549,14 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
|
||||
fn with_cache_updated(
|
||||
&mut self,
|
||||
result: Result<(), &'bump mut Node<'bump, T, A>>,
|
||||
) -> Result<(), &'bump mut Node<'bump, T, A>> {
|
||||
result: Result<(), <A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>>,
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>> {
|
||||
match result {
|
||||
Ok(_) => {
|
||||
A::update_cache_leaf(self);
|
||||
Ok(())
|
||||
}
|
||||
Err(new) => {
|
||||
Err(mut new) => {
|
||||
A::update_cache_leaf(self);
|
||||
A::update_cache_leaf(new.as_leaf_mut().unwrap());
|
||||
Err(new)
|
||||
|
@ -561,7 +571,7 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
mut offset: usize,
|
||||
value: T,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'bump mut Node<'bump, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'bump, Node<'bump, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
|
@ -593,17 +603,16 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
// need to split child
|
||||
let a = self.children[child_index].slice(0, offset);
|
||||
let b = self.children[child_index].slice(offset, self.children[child_index].atom_len());
|
||||
self.children[child_index] = BumpBox::new_in(a, self.bump);
|
||||
self.children[child_index] = self.bump.allocate(a);
|
||||
if self.children.len() >= A::MAX_CHILDREN_NUM - 1 {
|
||||
let next_node = self._split(notify);
|
||||
let mut next_node = self._split(notify);
|
||||
let next_leaf = next_node.as_leaf_mut().unwrap();
|
||||
if child_index < self.children.len() {
|
||||
notify(&value, self_ptr);
|
||||
notify(&b, self_ptr);
|
||||
self.children
|
||||
.insert(child_index + 1, BumpBox::new_in(value, self.bump));
|
||||
self.children
|
||||
.insert(child_index + 2, BumpBox::new_in(b, self.bump));
|
||||
.insert(child_index + 1, self.bump.allocate(value));
|
||||
self.children.insert(child_index + 2, self.bump.allocate(b));
|
||||
|
||||
let last_child = self.children.pop().unwrap();
|
||||
notify(&last_child, next_leaf);
|
||||
|
@ -612,23 +621,21 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
notify(&value, next_leaf);
|
||||
next_leaf.children.insert(
|
||||
child_index - self.children.len() + 1,
|
||||
BumpBox::new_in(value, self.bump),
|
||||
self.bump.allocate(value),
|
||||
);
|
||||
notify(&b, next_leaf);
|
||||
next_leaf.children.insert(
|
||||
child_index - self.children.len() + 2,
|
||||
BumpBox::new_in(b, self.bump),
|
||||
);
|
||||
next_leaf
|
||||
.children
|
||||
.insert(child_index - self.children.len() + 2, self.bump.allocate(b));
|
||||
}
|
||||
|
||||
return Err(next_node);
|
||||
}
|
||||
notify(&b, self);
|
||||
notify(&value, self);
|
||||
self.children.insert(child_index + 1, self.bump.allocate(b));
|
||||
self.children
|
||||
.insert(child_index + 1, BumpBox::new_in(b, self.bump));
|
||||
self.children
|
||||
.insert(child_index + 1, BumpBox::new_in(value, self.bump));
|
||||
.insert(child_index + 1, self.bump.allocate(value));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -657,7 +664,12 @@ impl<'bump, T: Rle, A: RleTreeTrait<T>> LeafNode<'bump, T, A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn children(&self) -> &[BumpBox<T>] {
|
||||
pub fn children(
|
||||
&self,
|
||||
) -> &<<A as RleTreeTrait<T>>::Arena as Arena>::Vec<
|
||||
'bump,
|
||||
<<A as RleTreeTrait<T>>::Arena as Arena>::Boxed<'bump, T>,
|
||||
> {
|
||||
&self.children
|
||||
}
|
||||
}
|
||||
|
@ -670,7 +682,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> LeafNode<'a, T, A> {
|
|||
start: Option<A::Int>,
|
||||
end: Option<A::Int>,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'a mut Node<'a, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
|
@ -693,7 +705,7 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> LeafNode<'a, T, A> {
|
|||
end.slice(del_relative_to, end.atom_len()),
|
||||
);
|
||||
|
||||
*end = BumpBox::new_in(left, self.bump);
|
||||
*end = self.bump.allocate(left);
|
||||
result = self._insert_with_split(del_end + 1, right, notify);
|
||||
handled = true;
|
||||
}
|
||||
|
@ -701,15 +713,16 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> LeafNode<'a, T, A> {
|
|||
|
||||
if !handled {
|
||||
if let Some(del_relative_from) = del_relative_from {
|
||||
self.children[del_start - 1] = BumpBox::new_in(
|
||||
self.children[del_start - 1].slice(0, del_relative_from),
|
||||
self.bump,
|
||||
);
|
||||
self.children[del_start - 1] = self
|
||||
.bump
|
||||
.allocate(self.children[del_start - 1].slice(0, del_relative_from));
|
||||
}
|
||||
if let Some(del_relative_to) = del_relative_to {
|
||||
let self_ptr = self as *mut _;
|
||||
let end = &mut self.children[del_end];
|
||||
*end = BumpBox::new_in(end.slice(del_relative_to, end.atom_len()), self.bump);
|
||||
*end = self
|
||||
.bump
|
||||
.allocate(end.slice(del_relative_to, end.atom_len()));
|
||||
notify(end, self_ptr);
|
||||
}
|
||||
}
|
||||
|
@ -731,30 +744,26 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> LeafNode<'a, T, A> {
|
|||
index: usize,
|
||||
value: T,
|
||||
notify: &mut F,
|
||||
) -> Result<(), &'a mut Node<'a, T, A>>
|
||||
) -> Result<(), <A::Arena as Arena>::Boxed<'a, Node<'a, T, A>>>
|
||||
where
|
||||
F: FnMut(&T, *mut LeafNode<'_, T, A>),
|
||||
{
|
||||
if self.children.len() == A::MAX_CHILDREN_NUM {
|
||||
let ans = self._split(notify);
|
||||
let mut ans = self._split(notify);
|
||||
if index <= self.children.len() {
|
||||
notify(&value, self);
|
||||
self.children
|
||||
.insert(index, BumpBox::new_in(value, self.bump));
|
||||
self.children.insert(index, self.bump.allocate(value));
|
||||
} else {
|
||||
let leaf = ans.as_leaf_mut().unwrap();
|
||||
notify(&value, leaf);
|
||||
leaf.children.insert(
|
||||
index - self.children.len(),
|
||||
BumpBox::new_in(value, self.bump),
|
||||
);
|
||||
leaf.children
|
||||
.insert(index - self.children.len(), self.bump.allocate(value));
|
||||
}
|
||||
|
||||
Err(ans)
|
||||
} else {
|
||||
notify(&value, self);
|
||||
self.children
|
||||
.insert(index, BumpBox::new_in(value, self.bump));
|
||||
self.children.insert(index, self.bump.allocate(value));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
use std::fmt::Debug;
|
||||
use std::{fmt::Debug, ops::Deref};
|
||||
|
||||
use bumpalo::Bump;
|
||||
use num::{traits::AsPrimitive, FromPrimitive, Integer};
|
||||
|
||||
use crate::{rle_trait::HasIndex, HasLength, Rle};
|
||||
|
||||
use super::node::{InternalNode, LeafNode, Node};
|
||||
use super::{
|
||||
arena::Arena,
|
||||
node::{InternalNode, LeafNode, Node},
|
||||
};
|
||||
|
||||
/// The position relative to a certain node.
|
||||
///
|
||||
|
@ -70,6 +74,7 @@ pub trait RleTreeTrait<T: Rle>: Sized + Debug {
|
|||
type Int: num::Integer + Copy + Debug + FromPrimitive;
|
||||
type InternalCache: Default + Debug + Eq + Clone;
|
||||
type LeafCache: Default + Debug + Eq + Clone;
|
||||
type Arena: Arena;
|
||||
|
||||
fn update_cache_leaf(node: &mut LeafNode<'_, T, Self>);
|
||||
fn update_cache_internal(node: &mut InternalNode<'_, T, Self>);
|
||||
|
@ -100,16 +105,18 @@ pub trait RleTreeTrait<T: Rle>: Sized + Debug {
|
|||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct CumulateTreeTrait<T: Rle, const MAX_CHILD: usize> {
|
||||
_phantom: std::marker::PhantomData<T>,
|
||||
pub struct CumulateTreeTrait<T: Rle, const MAX_CHILD: usize, TreeArena: Arena = Bump> {
|
||||
_phantom: std::marker::PhantomData<(T, TreeArena)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct GlobalTreeTrait<T: Rle, const MAX_CHILD: usize> {
|
||||
_phantom: std::marker::PhantomData<T>,
|
||||
pub struct GlobalTreeTrait<T: Rle, const MAX_CHILD: usize, TreeArena: Arena = Bump> {
|
||||
_phantom: std::marker::PhantomData<(T, TreeArena)>,
|
||||
}
|
||||
|
||||
impl<T: Rle, const MAX_CHILD: usize> RleTreeTrait<T> for CumulateTreeTrait<T, MAX_CHILD> {
|
||||
impl<T: Rle, const MAX_CHILD: usize, TreeArena: Arena> RleTreeTrait<T>
|
||||
for CumulateTreeTrait<T, MAX_CHILD, TreeArena>
|
||||
{
|
||||
const MAX_CHILDREN_NUM: usize = MAX_CHILD;
|
||||
|
||||
const MIN_CHILDREN_NUM: usize = Self::MAX_CHILDREN_NUM / 2;
|
||||
|
@ -119,6 +126,7 @@ impl<T: Rle, const MAX_CHILD: usize> RleTreeTrait<T> for CumulateTreeTrait<T, MA
|
|||
type InternalCache = usize;
|
||||
|
||||
type LeafCache = usize;
|
||||
type Arena = TreeArena;
|
||||
|
||||
fn update_cache_leaf(node: &mut LeafNode<'_, T, Self>) {
|
||||
node.cache = node
|
||||
|
@ -142,7 +150,7 @@ impl<T: Rle, const MAX_CHILD: usize> RleTreeTrait<T> for CumulateTreeTrait<T, MA
|
|||
|
||||
let mut last_cache = 0;
|
||||
for (i, child) in node.children().iter().enumerate() {
|
||||
last_cache = match child {
|
||||
last_cache = match child.deref() {
|
||||
Node::Internal(x) => {
|
||||
if index <= x.cache {
|
||||
return FindPosResult::new(i, index, Position::get_pos(index, child.len()));
|
||||
|
@ -253,8 +261,8 @@ pub struct Cache<I> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn get_cache<T: Rle + HasIndex, const MAX_CHILD: usize>(
|
||||
node: &Node<'_, T, GlobalTreeTrait<T, MAX_CHILD>>,
|
||||
fn get_cache<T: Rle + HasIndex, const MAX_CHILD: usize, TreeArena: Arena>(
|
||||
node: &Node<'_, T, GlobalTreeTrait<T, MAX_CHILD, TreeArena>>,
|
||||
) -> Cache<T::Int> {
|
||||
match node {
|
||||
Node::Internal(x) => x.cache,
|
||||
|
@ -262,7 +270,9 @@ fn get_cache<T: Rle + HasIndex, const MAX_CHILD: usize>(
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Rle + HasIndex, const MAX_CHILD: usize> RleTreeTrait<T> for GlobalTreeTrait<T, MAX_CHILD> {
|
||||
impl<T: Rle + HasIndex, const MAX_CHILD: usize, TreeArena: Arena> RleTreeTrait<T>
|
||||
for GlobalTreeTrait<T, MAX_CHILD, TreeArena>
|
||||
{
|
||||
const MAX_CHILDREN_NUM: usize = MAX_CHILD;
|
||||
|
||||
const MIN_CHILDREN_NUM: usize = Self::MAX_CHILDREN_NUM / 2;
|
||||
|
@ -271,6 +281,7 @@ impl<T: Rle + HasIndex, const MAX_CHILD: usize> RleTreeTrait<T> for GlobalTreeTr
|
|||
|
||||
type InternalCache = Cache<T::Int>;
|
||||
type LeafCache = Cache<T::Int>;
|
||||
type Arena = TreeArena;
|
||||
|
||||
fn update_cache_leaf(node: &mut LeafNode<'_, T, Self>) {
|
||||
if node.children.is_empty() {
|
||||
|
@ -299,7 +310,7 @@ impl<T: Rle + HasIndex, const MAX_CHILD: usize> RleTreeTrait<T> for GlobalTreeTr
|
|||
.map(|x| get_cache(x).end)
|
||||
.max()
|
||||
.unwrap();
|
||||
node.cache.start = get_cache(node.children()[0]).start;
|
||||
node.cache.start = get_cache(&node.children()[0]).start;
|
||||
}
|
||||
|
||||
fn find_pos_internal(
|
||||
|
@ -316,7 +327,7 @@ impl<T: Rle + HasIndex, const MAX_CHILD: usize> RleTreeTrait<T> for GlobalTreeTr
|
|||
// prefer Start than End
|
||||
if index == cache.end
|
||||
&& i + 1 < node.children.len()
|
||||
&& index == get_cache(node.children[i + 1]).start
|
||||
&& index == get_cache(&node.children[i + 1]).start
|
||||
{
|
||||
return FindPosResult::new(i + 1, index, Position::Start);
|
||||
}
|
||||
|
@ -396,7 +407,7 @@ impl<T: Rle + HasIndex, const MAX_CHILD: usize> RleTreeTrait<T> for GlobalTreeTr
|
|||
.max()
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(node.cache.start, get_cache(node.children()[0]).start);
|
||||
assert_eq!(node.cache.start, get_cache(&node.children()[0]).start);
|
||||
}
|
||||
|
||||
fn get_index(node: &LeafNode<'_, T, Self>, child_index: usize) -> Self::Int {
|
||||
|
|
Loading…
Reference in a new issue