mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-11 14:53:12 +00:00
refactor: simplify delete
This commit is contained in:
parent
105ab9b5ef
commit
95e514b329
1 changed files with 60 additions and 60 deletions
|
@ -1,9 +1,10 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::{BinaryHeap, HashMap, HashSet},
|
||||||
fmt::{Debug, Error, Formatter},
|
fmt::{Debug, Error, Formatter},
|
||||||
};
|
};
|
||||||
|
|
||||||
use fxhash::{FxBuildHasher, FxHashSet, FxHasher};
|
use fxhash::{FxBuildHasher, FxHashSet, FxHasher};
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::rle_tree::{
|
use crate::rle_tree::{
|
||||||
node::utils::distribute,
|
node::utils::distribute,
|
||||||
|
@ -540,37 +541,37 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
||||||
HashSet::with_capacity_and_hasher(zipper.len(), FxBuildHasher::default());
|
HashSet::with_capacity_and_hasher(zipper.len(), FxBuildHasher::default());
|
||||||
let mut should_skip: HashSet<NonNull<_>, _> =
|
let mut should_skip: HashSet<NonNull<_>, _> =
|
||||||
HashSet::with_capacity_and_hasher(zipper.len(), FxBuildHasher::default());
|
HashSet::with_capacity_and_hasher(zipper.len(), FxBuildHasher::default());
|
||||||
let mut zipper: Vec<(usize, NonNull<Node<'a, T, A>>)> = zipper
|
let mut depth_to_node: HashMap<isize, SmallVec<[NonNull<_>; 2]>, _> =
|
||||||
|
HashMap::with_capacity_and_hasher(zipper.len(), FxBuildHasher::default());
|
||||||
|
let mut zipper: BinaryHeap<(isize, NonNull<Node<'a, T, A>>)> = zipper
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(_, ptr)| {
|
.filter_map(|(i, mut ptr)| {
|
||||||
if visited.contains(ptr) {
|
// SAFETY: node_ptr points to a valid descendant of self
|
||||||
false
|
let node: &mut Node<'a, T, A> = unsafe { ptr.as_mut() };
|
||||||
|
if let Some(node) = node.as_internal() {
|
||||||
|
let in_ptr = node as *const InternalNode<'a, T, A>;
|
||||||
|
if removed.contains(&in_ptr) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if visited.contains(&ptr) {
|
||||||
|
None
|
||||||
} else {
|
} else {
|
||||||
visited.insert(*ptr);
|
depth_to_node.entry(i as isize).or_default().push(ptr);
|
||||||
true
|
visited.insert(ptr);
|
||||||
|
Some((-(i as isize), ptr))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
// visit in depth order, top to down (depth 0..inf)
|
// visit in depth order, top to down (depth 0..inf)
|
||||||
zipper.sort();
|
while let Some((reverse_depth, mut node_ptr)) = zipper.pop() {
|
||||||
let mut any_delete: bool;
|
|
||||||
loop {
|
|
||||||
any_delete = false;
|
|
||||||
for (_, mut node_ptr) in zipper.iter_mut() {
|
|
||||||
if should_skip.contains(&node_ptr) {
|
if should_skip.contains(&node_ptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: node_ptr points to a valid descendant of self
|
// SAFETY: node_ptr points to a valid descendant of self
|
||||||
let node: &mut Node<'a, T, A> = unsafe { node_ptr.as_mut() };
|
let node: &mut Node<'a, T, A> = unsafe { node_ptr.as_mut() };
|
||||||
if let Some(node) = node.as_internal() {
|
|
||||||
let ptr = node as *const InternalNode<'a, T, A>;
|
|
||||||
if removed.contains(&ptr) {
|
|
||||||
should_skip.insert(node_ptr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_assert!(node.children_num() <= A::MAX_CHILDREN_NUM);
|
debug_assert!(node.children_num() <= A::MAX_CHILDREN_NUM);
|
||||||
if node.children_num() >= A::MIN_CHILDREN_NUM {
|
if node.children_num() >= A::MIN_CHILDREN_NUM {
|
||||||
continue;
|
continue;
|
||||||
|
@ -598,21 +599,20 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
||||||
|
|
||||||
if to_delete {
|
if to_delete {
|
||||||
should_skip.insert(node_ptr);
|
should_skip.insert(node_ptr);
|
||||||
any_delete = true;
|
if let Some(parent) = depth_to_node.get(&(-reverse_depth - 1)).as_ref() {
|
||||||
|
for ptr in parent.iter() {
|
||||||
|
zipper.push((reverse_depth + 1, *ptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
node.remove();
|
node.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !any_delete {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self._root_shrink_levels_if_one_child();
|
self._root_shrink_levels_if_one_child();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _root_shrink_levels_if_one_child(&mut self) -> HashSet<*const InternalNode<'a, T, A>> {
|
fn _root_shrink_levels_if_one_child(&mut self) -> FxHashSet<*const InternalNode<'a, T, A>> {
|
||||||
let mut ans: HashSet<_> = Default::default();
|
let mut ans: HashSet<_, _> = FxHashSet::default();
|
||||||
while self.children.len() == 1 && self.children[0].as_internal().is_some() {
|
while self.children.len() == 1 && self.children[0].as_internal().is_some() {
|
||||||
let child = self.children.pop().unwrap();
|
let child = self.children.pop().unwrap();
|
||||||
let child_ptr = child.as_internal_mut().unwrap();
|
let child_ptr = child.as_internal_mut().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue