refactor: make bump optional in rle tree

This commit is contained in:
Zixuan Chen 2022-11-07 14:16:53 +08:00
parent ea2f1256b8
commit 24cd11f59e
7 changed files with 375 additions and 148 deletions

View file

@ -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) => {

View 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
}
}

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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(())
}
}

View file

@ -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 {