mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-22 12:57:20 +00:00
refactor: find pos result
This commit is contained in:
parent
72599b99d1
commit
a9134a9844
4 changed files with 67 additions and 46 deletions
|
@ -79,13 +79,12 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> RleTreeRaw<'a, T, A> {
|
|||
loop {
|
||||
match node {
|
||||
Node::Internal(internal_node) => {
|
||||
let (child_index, next, _) = A::find_pos_internal(internal_node, index);
|
||||
node = internal_node.children[child_index];
|
||||
index = next;
|
||||
let result = A::find_pos_internal(internal_node, index);
|
||||
node = internal_node.children[result.child_index];
|
||||
index = result.new_search_index;
|
||||
}
|
||||
Node::Leaf(leaf) => {
|
||||
let (child_index, _, _) = A::find_pos_leaf(leaf, index);
|
||||
return SafeCursor::new(leaf.into(), child_index);
|
||||
return SafeCursor::new(leaf.into(), A::find_pos_leaf(leaf, index).child_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::{
|
|||
fmt::{Debug, Error, Formatter},
|
||||
};
|
||||
|
||||
use crate::rle_tree::tree_trait::Position;
|
||||
use crate::rle_tree::tree_trait::{FindPosResult, Position};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -196,20 +196,20 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
}
|
||||
|
||||
fn _delete_start(&mut self, from: A::Int) -> (usize, Option<A::Int>) {
|
||||
let (index_from, relative_from, pos_from) = A::find_pos_internal(self, from);
|
||||
if pos_from == Position::Start {
|
||||
(index_from, None)
|
||||
let from = A::find_pos_internal(self, from);
|
||||
if from.pos == Position::Start {
|
||||
(from.child_index, None)
|
||||
} else {
|
||||
(index_from + 1, Some(relative_from))
|
||||
(from.child_index + 1, Some(from.new_search_index))
|
||||
}
|
||||
}
|
||||
|
||||
fn _delete_end(&mut self, to: A::Int) -> (usize, Option<A::Int>) {
|
||||
let (index_to, relative_to, pos_to) = A::find_pos_internal(self, to);
|
||||
if pos_to == Position::End {
|
||||
(index_to + 1, None)
|
||||
let to = A::find_pos_internal(self, to);
|
||||
if to.pos == Position::End {
|
||||
(to.child_index + 1, None)
|
||||
} else {
|
||||
(index_to, Some(relative_to))
|
||||
(to.child_index, Some(to.new_search_index))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,11 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> InternalNode<'a, T, A> {
|
|||
self.children.push(Node::new_leaf(self.bump, ptr));
|
||||
}
|
||||
|
||||
let (child_index, relative_idx, _) = A::find_pos_internal(self, index);
|
||||
let FindPosResult {
|
||||
child_index,
|
||||
new_search_index: relative_idx,
|
||||
..
|
||||
} = A::find_pos_internal(self, index);
|
||||
let child = &mut self.children[child_index];
|
||||
let new = match child {
|
||||
Node::Internal(child) => child.insert(relative_idx, value, notify),
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use crate::rle_tree::{cursor::SafeCursorMut, tree_trait::Position};
|
||||
use crate::rle_tree::{
|
||||
cursor::SafeCursorMut,
|
||||
tree_trait::{FindPosResult, Position},
|
||||
};
|
||||
use std::fmt::{Debug, Error, Formatter};
|
||||
|
||||
use super::*;
|
||||
|
@ -44,13 +47,13 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> LeafNode<'a, T, A> {
|
|||
|
||||
#[inline]
|
||||
pub fn get_cursor<'b>(&'b self, pos: A::Int) -> SafeCursor<'a, 'b, T, A> {
|
||||
let index = A::find_pos_leaf(self, pos).0;
|
||||
let index = A::find_pos_leaf(self, pos).child_index;
|
||||
SafeCursor::new(self.into(), index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_cursor_mut<'b>(&'b mut self, pos: A::Int) -> SafeCursorMut<'a, 'b, T, A> {
|
||||
let index = A::find_pos_leaf(self, pos).0;
|
||||
let index = A::find_pos_leaf(self, pos).child_index;
|
||||
SafeCursorMut::new(self.into(), index)
|
||||
}
|
||||
|
||||
|
@ -87,20 +90,20 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> LeafNode<'a, T, A> {
|
|||
}
|
||||
|
||||
fn _delete_start(&mut self, from: A::Int) -> (usize, Option<usize>) {
|
||||
let (index_from, relative_from, pos_from) = A::find_pos_leaf(self, from);
|
||||
if pos_from == Position::Start {
|
||||
(index_from, None)
|
||||
let result = A::find_pos_leaf(self, from);
|
||||
if result.pos == Position::Start {
|
||||
(result.child_index, None)
|
||||
} else {
|
||||
(index_from + 1, Some(relative_from))
|
||||
(result.child_index + 1, Some(result.new_search_index))
|
||||
}
|
||||
}
|
||||
|
||||
fn _delete_end(&mut self, to: A::Int) -> (usize, Option<usize>) {
|
||||
let (index_to, relative_to, pos_to) = A::find_pos_leaf(self, to);
|
||||
if pos_to == Position::End {
|
||||
(index_to + 1, None)
|
||||
let result = A::find_pos_leaf(self, to);
|
||||
if result.pos == Position::End {
|
||||
(result.child_index + 1, None)
|
||||
} else {
|
||||
(index_to, Some(relative_to))
|
||||
(result.child_index, Some(result.new_search_index))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +143,11 @@ impl<'a, T: Rle, A: RleTreeTrait<T>> LeafNode<'a, T, A> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let (mut index, mut offset, _pos) = A::find_pos_leaf(self, raw_index);
|
||||
let FindPosResult {
|
||||
child_index: mut index,
|
||||
new_search_index: mut offset,
|
||||
..
|
||||
} = A::find_pos_leaf(self, raw_index);
|
||||
let prev = {
|
||||
if offset == 0 && index > 0 {
|
||||
Some(&mut self.children[index - 1])
|
||||
|
|
|
@ -14,9 +14,19 @@ pub enum Position {
|
|||
}
|
||||
|
||||
pub struct FindPosResult<I> {
|
||||
child_index: usize,
|
||||
new_search_index: I,
|
||||
pos: Position,
|
||||
pub child_index: usize,
|
||||
pub new_search_index: I,
|
||||
pub pos: Position,
|
||||
}
|
||||
|
||||
impl<I> FindPosResult<I> {
|
||||
pub(crate) fn new(child_index: usize, new_search_index: I, pos: Position) -> Self {
|
||||
FindPosResult {
|
||||
child_index,
|
||||
new_search_index,
|
||||
pos,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RleTreeTrait<T: Rle>: Sized + Debug {
|
||||
|
@ -36,14 +46,14 @@ pub trait RleTreeTrait<T: Rle>: Sized + Debug {
|
|||
fn find_pos_internal(
|
||||
node: &InternalNode<'_, T, Self>,
|
||||
index: Self::Int,
|
||||
) -> (usize, Self::Int, Position);
|
||||
) -> FindPosResult<Self::Int>;
|
||||
|
||||
/// returns `(index, offset, pos)`
|
||||
///
|
||||
/// if `pos == Middle`, we need to split the node
|
||||
///
|
||||
/// - We need the third arg to determine whether the child is included or excluded
|
||||
fn find_pos_leaf(node: &LeafNode<'_, T, Self>, index: Self::Int) -> (usize, usize, Position);
|
||||
fn find_pos_leaf(node: &LeafNode<'_, T, Self>, index: Self::Int) -> FindPosResult<usize>;
|
||||
|
||||
fn len_leaf(node: &LeafNode<'_, T, Self>) -> Self::Int;
|
||||
fn len_internal(node: &InternalNode<'_, T, Self>) -> Self::Int;
|
||||
|
@ -83,19 +93,19 @@ impl<T: Rle, const MAX_CHILD: usize> RleTreeTrait<T> for CumulateTreeTrait<T, MA
|
|||
fn find_pos_internal(
|
||||
node: &InternalNode<'_, T, Self>,
|
||||
mut index: Self::Int,
|
||||
) -> (usize, Self::Int, Position) {
|
||||
) -> FindPosResult<usize> {
|
||||
let mut last_cache = 0;
|
||||
for (i, child) in node.children().iter().enumerate() {
|
||||
last_cache = match child {
|
||||
Node::Internal(x) => {
|
||||
if index <= x.cache {
|
||||
return (i, index, get_pos(index, child.len()));
|
||||
return FindPosResult::new(i, index, get_pos(index, child.len()));
|
||||
}
|
||||
x.cache
|
||||
}
|
||||
Node::Leaf(x) => {
|
||||
if index <= x.cache {
|
||||
return (i, index, get_pos(index, child.len()));
|
||||
return FindPosResult::new(i, index, get_pos(index, child.len()));
|
||||
}
|
||||
x.cache
|
||||
}
|
||||
|
@ -108,22 +118,19 @@ impl<T: Rle, const MAX_CHILD: usize> RleTreeTrait<T> for CumulateTreeTrait<T, MA
|
|||
dbg!(&node);
|
||||
assert_eq!(index, 0);
|
||||
}
|
||||
(node.children().len() - 1, last_cache, Position::End)
|
||||
FindPosResult::new(node.children().len() - 1, last_cache, Position::End)
|
||||
}
|
||||
|
||||
fn find_pos_leaf(
|
||||
node: &LeafNode<'_, T, Self>,
|
||||
mut index: Self::Int,
|
||||
) -> (usize, usize, Position) {
|
||||
fn find_pos_leaf(node: &LeafNode<'_, T, Self>, mut index: Self::Int) -> FindPosResult<usize> {
|
||||
for (i, child) in node.children().iter().enumerate() {
|
||||
if index < HasLength::len(&**child) {
|
||||
return (i, index, get_pos(index, child.len()));
|
||||
return FindPosResult::new(i, index, get_pos(index, child.len()));
|
||||
}
|
||||
|
||||
index -= HasLength::len(&**child);
|
||||
}
|
||||
|
||||
(
|
||||
FindPosResult::new(
|
||||
node.children().len() - 1,
|
||||
HasLength::len(&**node.children().last().unwrap()),
|
||||
Position::End,
|
||||
|
@ -226,19 +233,19 @@ impl<T: Rle + HasGlobalIndex, const MAX_CHILD: usize> RleTreeTrait<T>
|
|||
fn find_pos_internal(
|
||||
node: &InternalNode<'_, T, Self>,
|
||||
index: Self::Int,
|
||||
) -> (usize, Self::Int, Position) {
|
||||
) -> FindPosResult<Self::Int> {
|
||||
for (i, child) in node.children().iter().enumerate() {
|
||||
let cache = get_cache(child);
|
||||
if index <= cache.end {
|
||||
assert!(index >= cache.start);
|
||||
return (i, index, get_pos_global(index, cache));
|
||||
return FindPosResult::new(i, index, get_pos_global(index, cache));
|
||||
}
|
||||
}
|
||||
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
fn find_pos_leaf(node: &LeafNode<'_, T, Self>, index: Self::Int) -> (usize, usize, Position) {
|
||||
fn find_pos_leaf(node: &LeafNode<'_, T, Self>, index: Self::Int) -> FindPosResult<usize> {
|
||||
for (i, child) in node.children().iter().enumerate() {
|
||||
let cache = Cache {
|
||||
start: child.get_global_start(),
|
||||
|
@ -246,7 +253,11 @@ impl<T: Rle + HasGlobalIndex, const MAX_CHILD: usize> RleTreeTrait<T>
|
|||
};
|
||||
if index <= cache.end {
|
||||
assert!(index >= cache.start);
|
||||
return (i, (index - cache.start).as_(), get_pos_global(index, cache));
|
||||
return FindPosResult::new(
|
||||
i,
|
||||
(index - cache.start).as_(),
|
||||
get_pos_global(index, cache),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue