From 24cd11f59e26974d967c416f8a1c96a899bf2a79 Mon Sep 17 00:00:00 2001 From: Zixuan Chen Date: Mon, 7 Nov 2022 14:16:53 +0800 Subject: [PATCH] refactor: make bump optional in rle tree --- crates/rle/src/rle_tree.rs | 22 +- crates/rle/src/rle_tree/arena.rs | 189 ++++++++++++++++++ crates/rle/src/rle_tree/cursor.rs | 2 +- crates/rle/src/rle_tree/node.rs | 54 ++--- crates/rle/src/rle_tree/node/internal_impl.rs | 94 ++++----- crates/rle/src/rle_tree/node/leaf_impl.rs | 123 ++++++------ crates/rle/src/rle_tree/tree_trait.rs | 39 ++-- 7 files changed, 375 insertions(+), 148 deletions(-) create mode 100644 crates/rle/src/rle_tree/arena.rs diff --git a/crates/rle/src/rle_tree.rs b/crates/rle/src/rle_tree.rs index dd113a63..850a9f9d 100644 --- a/crates/rle/src/rle_tree.rs +++ b/crates/rle/src/rle_tree.rs @@ -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 + 'static> { - pub(crate) bump: Bump, + pub(crate) bump: A::Arena, #[borrows(bump)] - node: &'this mut Node<'this, T, A>, + #[not_covariant] + node: ::Boxed<'this, Node<'this, T, A>>, } impl + 'static> Default for RleTree { 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> RleTree { 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> RleTree { return None; } - node = internal_node.children[result.child_index]; + node = &internal_node.children[result.child_index]; index = result.offset; } Node::Leaf(leaf) => { diff --git a/crates/rle/src/rle_tree/arena.rs b/crates/rle/src/rle_tree/arena.rs new file mode 100644 index 00000000..4a3124eb --- /dev/null +++ b/crates/rle/src/rle_tree/arena.rs @@ -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 + IndexMut + Deref + DerefMut + Debug +{ + type Arena; + type Drain<'a>: Iterator + where + Self:'a; + + fn drain<'a, R>(&'a mut self, range: R) -> Self::Drain<'a> + where + R: RangeBounds; + + fn push(&mut self, value: T); + fn pop(&mut self) -> Option; + 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(&mut self, range: R, replace_with: I) + where + R: RangeBounds, + I: IntoIterator; +} + +pub trait Arena: Debug + Default { + type Boxed<'a, T>: Debug + Deref + 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, + { + // 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 { + 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(&mut self, range: R, replace_with: I) + where + R: RangeBounds, + I: IntoIterator, + { + self.splice(range, replace_with); + } +} + +impl<'v, T: Debug + 'v> VecTrait<'v, T> for Vec { + 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, + { + self.drain(range) + } + + #[inline(always)] + fn push(&mut self, value: T) { + self.push(value) + } + + #[inline(always)] + fn pop(&mut self) -> Option { + 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(&mut self, range: R, replace_with: I) + where + R: RangeBounds, + I: IntoIterator, + { + 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 where T: 'a + Debug; + type Vec<'a, T> = Vec 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 + } +} diff --git a/crates/rle/src/rle_tree/cursor.rs b/crates/rle/src/rle_tree/cursor.rs index e48eb3a5..bb3cb296 100644 --- a/crates/rle/src/rle_tree/cursor.rs +++ b/crates/rle/src/rle_tree/cursor.rs @@ -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> { +pub struct UnsafeCursor<'tree, T: Rle, A: RleTreeTrait + 'tree> { pub leaf: NonNull>, pub index: usize, pub offset: usize, diff --git a/crates/rle/src/rle_tree/node.rs b/crates/rle/src/rle_tree/node.rs index d3950da2..92f6b73e 100644 --- a/crates/rle/src/rle_tree/node.rs +++ b/crates/rle/src/rle_tree/node.rs @@ -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> { Leaf(LeafNode<'a, T, A>), } -pub struct InternalNode<'a, T: Rle, A: RleTreeTrait> { - bump: &'a Bump, +pub struct InternalNode<'a, T: Rle + 'a, A: RleTreeTrait + 'a> { + bump: &'a A::Arena, pub(crate) parent: Option>>, - pub(super) children: BumpVec<'a, &'a mut Node<'a, T, A>>, + pub(super) children: + ::Vec<'a, ::Boxed<'a, Node<'a, T, A>>>, pub cache: A::InternalCache, _pin: PhantomPinned, _a: PhantomData, @@ -33,10 +37,10 @@ pub struct InternalNode<'a, T: Rle, A: RleTreeTrait> { // TODO: remove bump field // TODO: remove parent field? // TODO: only one child? -pub struct LeafNode<'a, T: Rle, A: RleTreeTrait> { - bump: &'a Bump, +pub struct LeafNode<'a, T: Rle + 'a, A: RleTreeTrait> { + bump: &'a A::Arena, pub(crate) parent: NonNull>, - pub(crate) children: BumpVec<'a, BumpBox<'a, T>>, + pub(crate) children: ::Vec<'a, ::Boxed<'a, T>>, pub(crate) prev: Option>>, pub(crate) next: Option>>, pub cache: A::LeafCache, @@ -52,13 +56,16 @@ pub(crate) enum Either { impl<'a, T: Rle, A: RleTreeTrait> Node<'a, T, A> { #[inline] - fn _new_internal(bump: &'a Bump, parent: Option>>) -> Self { + fn _new_internal(bump: &'a A::Arena, parent: Option>>) -> Self { Self::Internal(InternalNode::new(bump, parent)) } #[inline] - fn new_leaf(bump: &'a Bump, parent: NonNull>) -> &'a mut Self { - bump.alloc(Self::Leaf(LeafNode::new(bump, parent))) + fn new_leaf( + bump: &'a A::Arena, + parent: NonNull>, + ) -> ::Boxed<'a, Self> { + bump.allocate(Self::Leaf(LeafNode::new(bump, parent))) } #[inline] @@ -126,7 +133,7 @@ impl<'a, T: Rle, A: RleTreeTrait> 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> 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> 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> 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> 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> 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> 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); } } diff --git a/crates/rle/src/rle_tree/node/internal_impl.rs b/crates/rle/src/rle_tree/node/internal_impl.rs index 586b5a22..a4a53795 100644 --- a/crates/rle/src/rle_tree/node/internal_impl.rs +++ b/crates/rle/src/rle_tree/node/internal_impl.rs @@ -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> InternalNode<'a, T, A> { - pub fn new(bump: &'a Bump, parent: Option>) -> Self { + pub fn new(bump: &'a A::Arena, parent: Option>) -> Self { Self { bump, parent, - children: BumpVec::with_capacity_in(A::MAX_CHILDREN_NUM, bump), + children: ::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> 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) -> ::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> 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> InternalNode<'a, T, A> { } #[inline] - pub fn children(&self) -> &[&'a mut Node<'a, T, A>] { + pub fn children(&self) -> &[::Boxed<'a, Node<'a, T, A>>] { &self.children } @@ -62,7 +64,7 @@ impl<'a, T: Rle, A: RleTreeTrait> 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> 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> 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> InternalNode<'a, T, A> { visited: &mut SmallVec<[(usize, NonNull>); 8]>, depth: usize, notify: &mut F, - ) -> Result<(), &'a mut Node<'a, T, A>> + ) -> Result<(), ::Boxed<'a, Node<'a, T, A>>> where F: FnMut(&T, *mut LeafNode<'_, T, A>), { @@ -163,17 +165,15 @@ impl<'a, T: Rle, A: RleTreeTrait> 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); 2]> = smallvec::smallvec![]; + let mut insertions: SmallVec<[(usize, ::Boxed<'a, Node>); 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> 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> 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> 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<::Boxed<'a, Node<'a, T, A>>>)>, + ) -> Result<(), Vec<::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<::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), + <::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> 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> 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> 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> 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> 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> InternalNode<'a, T, A> { index: A::Int, value: T, notify: &mut F, - ) -> Result<(), &'a mut Node<'a, T, A>> + ) -> Result<(), ::Boxed<'a, Node<'a, T, A>>> where F: FnMut(&T, *mut LeafNode<'_, T, A>), { @@ -426,7 +430,7 @@ impl<'a, T: Rle, A: RleTreeTrait> 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> 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: ::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> InternalNode<'a, T, A> { index: A::Int, value: T, notify: &mut F, - ) -> Result<(), &'a mut Node<'a, T, A>> + ) -> Result<(), ::Boxed<'a, Node<'a, T, A>>> where F: FnMut(&T, *mut LeafNode<'_, T, A>), { @@ -480,7 +484,7 @@ impl<'a, T: Rle, A: RleTreeTrait> 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> 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: ::Boxed<'a, Node<'a, T, A>>, + ) -> Result<(), ::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> 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> 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> 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: ::Boxed<'a, Node<'a, T, A>>, + ) -> Result<(), ::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); diff --git a/crates/rle/src/rle_tree/node/leaf_impl.rs b/crates/rle/src/rle_tree/node/leaf_impl.rs index 161aea34..16c75081 100644 --- a/crates/rle/src/rle_tree/node/leaf_impl.rs +++ b/crates/rle/src/rle_tree/node/leaf_impl.rs @@ -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> LeafNode<'bump, T, A> { #[inline] - pub fn new(bump: &'bump Bump, parent: NonNull>) -> Self { + pub fn new(bump: &'bump A::Arena, parent: NonNull>) -> Self { Self { bump, parent, - children: BumpVec::with_capacity_in(A::MAX_CHILDREN_NUM, bump), + children: <::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> LeafNode<'bump, T, A> { } #[inline] - fn _split(&mut self, notify: &mut F) -> &'bump mut Node<'bump, T, A> + fn _split(&mut self, notify: &mut F) -> ::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> LeafNode<'bump, T, A> { &mut self, value: T, notify: &mut F, - ) -> Result<(), &'bump mut Node<'bump, T, A>> + ) -> Result<(), ::Boxed<'bump, Node<'bump, T, A>>> where F: FnMut(&T, *mut LeafNode<'_, T, A>), { @@ -96,7 +100,7 @@ impl<'bump, T: Rle, A: RleTreeTrait> 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> 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> LeafNode<'bump, T, A> { raw_index: A::Int, value: T, notify: &mut F, - ) -> Result<(), &'bump mut Node<'bump, T, A>> + ) -> Result<(), ::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> LeafNode<'bump, T, A> { offset: usize, value: T, notify: &mut F, - ) -> Result<(), &'bump mut Node<'bump, T, A>> + ) -> Result<(), ::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> LeafNode<'bump, T, A> { len: usize, update_fn: U, notify: &mut F, - ) -> Result<(), &'bump mut Node<'bump, T, A>> + ) -> Result<(), ::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> 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> 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> 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> 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<::Boxed<'bump, Node<'bump, T, A>>>> where F: FnMut(&T, *mut LeafNode<'_, T, A>), { @@ -458,8 +462,14 @@ impl<'bump, T: Rle, A: RleTreeTrait> LeafNode<'bump, T, A> { } } - let mut new_children: Vec> = 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, + <::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> 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> 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> 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<(), ::Boxed<'bump, Node<'bump, T, A>>>, + ) -> Result<(), ::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> LeafNode<'bump, T, A> { mut offset: usize, value: T, notify: &mut F, - ) -> Result<(), &'bump mut Node<'bump, T, A>> + ) -> Result<(), ::Boxed<'bump, Node<'bump, T, A>>> where F: FnMut(&T, *mut LeafNode<'_, T, A>), { @@ -593,17 +603,16 @@ impl<'bump, T: Rle, A: RleTreeTrait> 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> 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> LeafNode<'bump, T, A> { } #[inline] - pub fn children(&self) -> &[BumpBox] { + pub fn children( + &self, + ) -> &<>::Arena as Arena>::Vec< + 'bump, + <>::Arena as Arena>::Boxed<'bump, T>, + > { &self.children } } @@ -670,7 +682,7 @@ impl<'a, T: Rle, A: RleTreeTrait> LeafNode<'a, T, A> { start: Option, end: Option, notify: &mut F, - ) -> Result<(), &'a mut Node<'a, T, A>> + ) -> Result<(), ::Boxed<'a, Node<'a, T, A>>> where F: FnMut(&T, *mut LeafNode<'_, T, A>), { @@ -693,7 +705,7 @@ impl<'a, T: Rle, A: RleTreeTrait> 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> 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> LeafNode<'a, T, A> { index: usize, value: T, notify: &mut F, - ) -> Result<(), &'a mut Node<'a, T, A>> + ) -> Result<(), ::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(()) } } diff --git a/crates/rle/src/rle_tree/tree_trait.rs b/crates/rle/src/rle_tree/tree_trait.rs index 22c285dd..7826c1c1 100644 --- a/crates/rle/src/rle_tree/tree_trait.rs +++ b/crates/rle/src/rle_tree/tree_trait.rs @@ -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: 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: Sized + Debug { } #[derive(Debug, Default)] -pub struct CumulateTreeTrait { - _phantom: std::marker::PhantomData, +pub struct CumulateTreeTrait { + _phantom: std::marker::PhantomData<(T, TreeArena)>, } #[derive(Debug, Default)] -pub struct GlobalTreeTrait { - _phantom: std::marker::PhantomData, +pub struct GlobalTreeTrait { + _phantom: std::marker::PhantomData<(T, TreeArena)>, } -impl RleTreeTrait for CumulateTreeTrait { +impl RleTreeTrait + for CumulateTreeTrait +{ const MAX_CHILDREN_NUM: usize = MAX_CHILD; const MIN_CHILDREN_NUM: usize = Self::MAX_CHILDREN_NUM / 2; @@ -119,6 +126,7 @@ impl RleTreeTrait for CumulateTreeTrait) { node.cache = node @@ -142,7 +150,7 @@ impl RleTreeTrait for CumulateTreeTrait { if index <= x.cache { return FindPosResult::new(i, index, Position::get_pos(index, child.len())); @@ -253,8 +261,8 @@ pub struct Cache { } #[inline] -fn get_cache( - node: &Node<'_, T, GlobalTreeTrait>, +fn get_cache( + node: &Node<'_, T, GlobalTreeTrait>, ) -> Cache { match node { Node::Internal(x) => x.cache, @@ -262,7 +270,9 @@ fn get_cache( } } -impl RleTreeTrait for GlobalTreeTrait { +impl RleTreeTrait + for GlobalTreeTrait +{ const MAX_CHILDREN_NUM: usize = MAX_CHILD; const MIN_CHILDREN_NUM: usize = Self::MAX_CHILDREN_NUM / 2; @@ -271,6 +281,7 @@ impl RleTreeTrait for GlobalTreeTr type InternalCache = Cache; type LeafCache = Cache; + type Arena = TreeArena; fn update_cache_leaf(node: &mut LeafNode<'_, T, Self>) { if node.children.is_empty() { @@ -299,7 +310,7 @@ impl RleTreeTrait 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 RleTreeTrait 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 RleTreeTrait 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 {