From 41167b4af031aeb174d7abd98557b8f50361aeff Mon Sep 17 00:00:00 2001 From: Zixuan Chen Date: Sun, 9 Oct 2022 20:23:37 +0800 Subject: [PATCH] refactor: simplify lifetime of cursor --- .../loro-core/src/container/text/tracker.rs | 1 - .../src/container/text/tracker/content_map.rs | 8 +-- .../src/container/text/tracker/cursor_map.rs | 4 +- .../src/container/text/tracker/yata.rs | 5 +- crates/rle/src/rle_tree.rs | 30 ++++----- crates/rle/src/rle_tree/cursor.rs | 62 ++++++++----------- crates/rle/src/rle_tree/iter.rs | 36 +++++------ crates/rle/src/rle_tree/node/leaf_impl.rs | 4 +- 8 files changed, 71 insertions(+), 79 deletions(-) diff --git a/crates/loro-core/src/container/text/tracker.rs b/crates/loro-core/src/container/text/tracker.rs index 0a7022f1..81cef242 100644 --- a/crates/loro-core/src/container/text/tracker.rs +++ b/crates/loro-core/src/container/text/tracker.rs @@ -1,4 +1,3 @@ -use crdt_list::crdt::ListCrdt; use rle::HasLength; use crate::{ diff --git a/crates/loro-core/src/container/text/tracker/content_map.rs b/crates/loro-core/src/container/text/tracker/content_map.rs index 8a45201f..397eb355 100644 --- a/crates/loro-core/src/container/text/tracker/content_map.rs +++ b/crates/loro-core/src/container/text/tracker/content_map.rs @@ -18,7 +18,7 @@ pub(super) struct ContentMap(RleTree); struct CursorWithId<'tree> { id: ID, - cursor: UnsafeCursor<'tree, 'static, YSpan, YSpanTreeTrait>, + cursor: UnsafeCursor<'tree, YSpan, YSpanTreeTrait>, } impl ContentMap { @@ -37,7 +37,7 @@ impl ContentMap { /// When we insert a new [YSpan] at given position, we need to calculate its `originLeft` and `originRight` fn get_sibling_at(&self, pos: usize) -> (Option>, Option>) { if let Some(cursor) = self.get(pos) { - let cursor: SafeCursor<'_, 'static, YSpan, YSpanTreeTrait> = + let cursor: SafeCursor<'_, YSpan, YSpanTreeTrait> = // SAFETY: we only change the lifetime of the cursor; the returned lifetime is kinda wrong in this situation // because Bumpalo's lifetime is static due to the self-referential structure limitation; Maybe there is a better way? unsafe { std::mem::transmute(cursor) }; @@ -153,8 +153,8 @@ impl DerefMut for ContentMap { } } -pub(super) fn change_status<'a, 'b: 'a>( - cursor: &mut SafeCursorMut<'a, 'b, YSpan, YSpanTreeTrait>, +pub(super) fn change_status( + cursor: &mut SafeCursorMut<'_, YSpan, YSpanTreeTrait>, change: StatusChange, ) { let value = cursor.as_mut(); diff --git a/crates/loro-core/src/container/text/tracker/cursor_map.rs b/crates/loro-core/src/container/text/tracker/cursor_map.rs index a0fc9a63..0b0d5908 100644 --- a/crates/loro-core/src/container/text/tracker/cursor_map.rs +++ b/crates/loro-core/src/container/text/tracker/cursor_map.rs @@ -25,7 +25,7 @@ pub(super) enum Marker { } impl Marker { - pub fn as_cursor(&self, id: ID) -> Option> { + pub fn as_cursor(&self, id: ID) -> Option> { match self { Marker::Insert { ptr, len: _ } => { // SAFETY: tree data is always valid @@ -53,7 +53,7 @@ impl Marker { pub fn as_cursor_mut( &mut self, id: ID, - ) -> Option> { + ) -> Option> { match self { Marker::Insert { ptr, len: _ } => { // SAFETY: tree data is always valid diff --git a/crates/loro-core/src/container/text/tracker/yata.rs b/crates/loro-core/src/container/text/tracker/yata.rs index c90f1dfd..b46fba64 100644 --- a/crates/loro-core/src/container/text/tracker/yata.rs +++ b/crates/loro-core/src/container/text/tracker/yata.rs @@ -52,9 +52,9 @@ impl ListCrdt for YataImpl { type Set = OpSpanSet; - type Cursor<'a> = SafeCursorMut<'a, 'static, YSpan, YSpanTreeTrait>; + type Cursor<'a> = SafeCursorMut<'a, YSpan, YSpanTreeTrait>; - type Iterator<'a> = IterMut<'a, 'static, YSpan, YSpanTreeTrait>; + type Iterator<'a> = IterMut<'a, YSpan, YSpanTreeTrait>; fn iter( container: &mut Self::Container, @@ -173,6 +173,7 @@ mod test { #[cfg(feature = "fuzzing")] pub mod fuzz { + #![allow(unused_imports)] use crdt_list::{ test::{Action, TestFramework}, yata::Yata, diff --git a/crates/rle/src/rle_tree.rs b/crates/rle/src/rle_tree.rs index 7bb41e87..24bec545 100644 --- a/crates/rle/src/rle_tree.rs +++ b/crates/rle/src/rle_tree.rs @@ -60,7 +60,7 @@ impl> RleTree { /// return a cursor at the given index #[inline] - pub fn get(&self, mut index: A::Int) -> Option> { + pub fn get(&self, mut index: A::Int) -> Option> { self.with_node(|mut node| { loop { match node { @@ -97,7 +97,7 @@ impl> RleTree { /// return the first valid cursor after the given index #[inline] - fn get_cursor_ge(&self, mut index: A::Int) -> Option> { + fn get_cursor_ge(&self, mut index: A::Int) -> Option> { self.with_node(|mut node| { loop { match node { @@ -133,24 +133,24 @@ impl> RleTree { } #[inline] - pub fn get_mut(&mut self, index: A::Int) -> Option> { + pub fn get_mut(&mut self, index: A::Int) -> Option> { let cursor = self.get(index); cursor.map(|x| SafeCursorMut(x.0)) } #[inline] - pub fn iter(&self) -> iter::Iter<'_, '_, T, A> { + pub fn iter(&self) -> iter::Iter<'_, T, A> { // SAFETY: the cursor and iter cannot outlive self self.with_node(|node| unsafe { - std::mem::transmute(iter::Iter::new(node.get_first_leaf())) + iter::Iter::new(std::mem::transmute(node.get_first_leaf())) }) } #[inline] - pub fn iter_mut(&mut self) -> iter::IterMut<'_, '_, T, A> { + pub fn iter_mut(&mut self) -> iter::IterMut<'_, T, A> { // SAFETY: the cursor and iter cannot outlive self self.with_node_mut(|node| unsafe { - std::mem::transmute(iter::IterMut::new(node.get_first_leaf_mut())) + iter::IterMut::new(std::mem::transmute(node.get_first_leaf_mut())) }) } @@ -161,9 +161,9 @@ impl> RleTree { pub fn iter_mut_in( &mut self, - start: Option>, - end: Option>, - ) -> iter::IterMut<'_, '_, T, A> { + start: Option>, + end: Option>, + ) -> iter::IterMut<'_, T, A> { if self.empty() || (start.is_none() && end.is_none()) { self.iter_mut() } else { @@ -174,10 +174,10 @@ impl> RleTree { let start = start.unwrap_or_else(|| { std::mem::transmute(SafeCursor::new(leaf, 0, 0, Position::Start, 0)) }); - let start: SafeCursorMut<'_, '_, T, A> = SafeCursorMut(start.0); - std::mem::transmute::<_, iter::IterMut<'_, '_, T, A>>(iter::IterMut::from_cursor( - std::mem::transmute::<_, SafeCursorMut<'_, '_, T, A>>(start), - std::mem::transmute(end), + let start: SafeCursorMut<'_, T, A> = SafeCursorMut(start.0); + std::mem::transmute::<_, iter::IterMut<'_, T, A>>(iter::IterMut::from_cursor( + std::mem::transmute::<_, SafeCursorMut<'_, T, A>>(start), + end, )) }) } @@ -204,7 +204,7 @@ impl> RleTree { }) } - pub fn iter_range(&self, start: A::Int, end: Option) -> iter::Iter<'_, '_, T, A> { + pub fn iter_range(&self, start: A::Int, end: Option) -> iter::Iter<'_, T, A> { let cursor_from = self.get_cursor_ge(start); if cursor_from.is_none() { return iter::Iter::new(None); diff --git a/crates/rle/src/rle_tree/cursor.rs b/crates/rle/src/rle_tree/cursor.rs index d5bd5b85..8a066263 100644 --- a/crates/rle/src/rle_tree/cursor.rs +++ b/crates/rle/src/rle_tree/cursor.rs @@ -6,8 +6,8 @@ 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(PartialEq, Eq, Debug)] -pub struct UnsafeCursor<'tree, 'bump, T: Rle, A: RleTreeTrait> { - pub leaf: NonNull>, +pub struct UnsafeCursor<'tree, T: Rle, A: RleTreeTrait> { + pub leaf: NonNull>, pub index: usize, pub offset: usize, pub pos: Position, @@ -15,7 +15,7 @@ pub struct UnsafeCursor<'tree, 'bump, T: Rle, A: RleTreeTrait> { _phantom: PhantomData<&'tree usize>, } -impl<'tree, 'bump, T: Rle, A: RleTreeTrait> Clone for UnsafeCursor<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> Clone for UnsafeCursor<'tree, T, A> { #[inline] fn clone(&self) -> Self { Self { @@ -29,32 +29,28 @@ impl<'tree, 'bump, T: Rle, A: RleTreeTrait> Clone for UnsafeCursor<'tree, 'bu } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Copy for UnsafeCursor<'tree, 'bump, T, A> {} +impl<'tree, T: Rle, A: RleTreeTrait> Copy for UnsafeCursor<'tree, T, A> {} #[repr(transparent)] #[derive(Debug)] -pub struct SafeCursor<'tree, 'bump, T: Rle, A: RleTreeTrait>( - pub(crate) UnsafeCursor<'tree, 'bump, T, A>, -); +pub struct SafeCursor<'tree, T: Rle, A: RleTreeTrait>(pub(crate) UnsafeCursor<'tree, T, A>); #[repr(transparent)] #[derive(Debug)] -pub struct SafeCursorMut<'tree, 'bump, T: Rle, A: RleTreeTrait>( - pub(crate) UnsafeCursor<'tree, 'bump, T, A>, -); +pub struct SafeCursorMut<'tree, T: Rle, A: RleTreeTrait>(pub(crate) UnsafeCursor<'tree, T, A>); -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Clone for SafeCursor<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> Clone for SafeCursor<'tree, T, A> { fn clone(&self) -> Self { Self(self.0) } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Copy for SafeCursor<'tree, 'bump, T, A> {} +impl<'tree, T: Rle, A: RleTreeTrait> Copy for SafeCursor<'tree, T, A> {} -impl<'tree, 'bump, T: Rle, A: RleTreeTrait> UnsafeCursor<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> UnsafeCursor<'tree, T, A> { #[inline] pub(crate) fn new( - leaf: NonNull>, + leaf: NonNull>, index: usize, offset: usize, pos: Position, @@ -71,7 +67,7 @@ impl<'tree, 'bump, T: Rle, A: RleTreeTrait> UnsafeCursor<'tree, 'bump, T, A> } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> UnsafeCursor<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> UnsafeCursor<'tree, T, A> { /// # Safety /// /// we need to make sure that the cursor is still valid @@ -209,7 +205,7 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> UnsafeCursor<'tree, 'bump, } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> AsRef for SafeCursor<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> AsRef for SafeCursor<'tree, T, A> { #[inline] fn as_ref(&self) -> &'tree T { // SAFETY: SafeCursor is a shared reference to the tree @@ -217,13 +213,13 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> AsRef for SafeCursor<'t } } -impl<'tree, 'bump, T: Rle, A: RleTreeTrait> SafeCursor<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> SafeCursor<'tree, T, A> { /// # Safety /// /// Users should make sure aht leaf is pointing to a valid LeafNode with 'bump lifetime, and index is inbound #[inline] pub unsafe fn new( - leaf: NonNull>, + leaf: NonNull>, index: usize, offset: usize, pos: Position, @@ -233,7 +229,7 @@ impl<'tree, 'bump, T: Rle, A: RleTreeTrait> SafeCursor<'tree, 'bump, T, A> { } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursor<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> SafeCursor<'tree, T, A> { #[inline] pub fn as_tree_ref(&self) -> &'tree T { // SAFETY: SafeCursor is a shared reference to the tree @@ -253,7 +249,7 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursor<'tree, 'bump, T } #[inline] - pub fn leaf(&self) -> &'tree LeafNode<'bump, T, A> { + pub fn leaf(&self) -> &'tree LeafNode<'tree, T, A> { // SAFETY: SafeCursor has shared reference lifetime to the tree unsafe { self.0.leaf.as_ref() } } @@ -274,14 +270,12 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursor<'tree, 'bump, T } #[inline] - pub fn unwrap(self) -> UnsafeCursor<'tree, 'bump, T, A> { + pub fn unwrap(self) -> UnsafeCursor<'tree, T, A> { self.0 } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> AsRef - for SafeCursorMut<'tree, 'bump, T, A> -{ +impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> AsRef for SafeCursorMut<'tree, T, A> { #[inline] fn as_ref(&self) -> &T { // SAFETY: SafeCursorMut is a exclusive reference to the tree @@ -289,7 +283,7 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> AsRef } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursorMut<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> SafeCursorMut<'tree, T, A> { #[inline] pub fn as_ref_(&self) -> &'tree T { // SAFETY: SafeCursorMut is a exclusive reference to the tree @@ -297,13 +291,13 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursorMut<'tree, 'bump } #[inline] - pub fn leaf(&self) -> &'tree LeafNode<'bump, T, A> { + pub fn leaf(&self) -> &'tree LeafNode<'tree, T, A> { // SAFETY: SafeCursorMut is a exclusive reference to the tree unsafe { self.0.leaf.as_ref() } } #[inline] - pub fn leaf_mut(&mut self) -> &'tree mut LeafNode<'bump, T, A> { + pub fn leaf_mut(&mut self) -> &'tree mut LeafNode<'tree, T, A> { // SAFETY: SafeCursorMut is a exclusive reference to the tree unsafe { self.0.leaf.as_mut() } } @@ -314,13 +308,13 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursorMut<'tree, 'bump } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursorMut<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> SafeCursorMut<'tree, T, A> { /// # Safety /// /// User must be sure that there is not exclusive reference to the tree and leaf pointer is valid #[inline] pub unsafe fn new( - leaf: NonNull>, + leaf: NonNull>, index: usize, offset: usize, pos: Position, @@ -353,7 +347,7 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursorMut<'tree, 'bump } #[inline] - pub fn unwrap(self) -> UnsafeCursor<'tree, 'bump, T, A> { + pub fn unwrap(self) -> UnsafeCursor<'tree, T, A> { self.0 } @@ -410,9 +404,7 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> SafeCursorMut<'tree, 'bump } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> AsMut - for SafeCursorMut<'tree, 'bump, T, A> -{ +impl<'tree, T: Rle, A: RleTreeTrait> AsMut for SafeCursorMut<'tree, T, A> { #[inline] fn as_mut(&mut self) -> &mut T { // SAFETY: SafeCursorMut is a exclusive reference to the tree so we are safe to @@ -421,7 +413,7 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> AsMut } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Deref for SafeCursor<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> Deref for SafeCursor<'tree, T, A> { type Target = T; fn deref(&self) -> &Self::Target { @@ -429,7 +421,7 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Deref for SafeCursor<'tree } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Deref for SafeCursorMut<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> Deref for SafeCursorMut<'tree, T, A> { type Target = T; fn deref(&self) -> &Self::Target { diff --git a/crates/rle/src/rle_tree/iter.rs b/crates/rle/src/rle_tree/iter.rs index 964f0ea2..df5c2d4d 100644 --- a/crates/rle/src/rle_tree/iter.rs +++ b/crates/rle/src/rle_tree/iter.rs @@ -7,19 +7,19 @@ use super::{ }; /// cursor's and `end_cursor`'s length means nothing in this context -pub struct Iter<'some, 'bump, T: Rle, A: RleTreeTrait> { - cursor: Option>, - end_cursor: Option>, +pub struct Iter<'some, T: Rle, A: RleTreeTrait> { + cursor: Option>, + end_cursor: Option>, } -pub struct IterMut<'some, 'bump, T: Rle, A: RleTreeTrait> { - cursor: Option>, - end_cursor: Option>, +pub struct IterMut<'some, T: Rle, A: RleTreeTrait> { + cursor: Option>, + end_cursor: Option>, } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> IterMut<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> IterMut<'tree, T, A> { #[inline] - pub fn new(node: Option<&'tree mut LeafNode<'bump, T, A>>) -> Self { + pub fn new(node: Option<&'tree mut LeafNode<'tree, T, A>>) -> Self { if node.is_none() { return Self { cursor: None, @@ -36,8 +36,8 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> IterMut<'tree, 'bump, T, A #[inline] pub fn from_cursor( - mut start: SafeCursorMut<'tree, 'bump, T, A>, - mut end: Option>, + mut start: SafeCursorMut<'tree, T, A>, + mut end: Option>, ) -> Self { if start.0.pos == Position::After { match start.next_elem_start() { @@ -70,9 +70,9 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> IterMut<'tree, 'bump, T, A } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Iter<'tree, 'bump, T, A> { +impl<'tree, T: Rle, A: RleTreeTrait> Iter<'tree, T, A> { #[inline] - pub fn new(node: Option<&'tree LeafNode<'bump, T, A>>) -> Self { + pub fn new(node: Option<&'tree LeafNode<'tree, T, A>>) -> Self { if node.is_none() { return Self { cursor: None, @@ -89,8 +89,8 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Iter<'tree, 'bump, T, A> { #[inline] pub fn from_cursor( - mut start: SafeCursor<'tree, 'bump, T, A>, - mut end: Option>, + mut start: SafeCursor<'tree, T, A>, + mut end: Option>, ) -> Option { if start.0.pos == Position::After { start = start.next_elem_start()? @@ -109,8 +109,8 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Iter<'tree, 'bump, T, A> { } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Iterator for Iter<'tree, 'bump, T, A> { - type Item = SafeCursor<'tree, 'bump, T, A>; +impl<'tree, T: Rle, A: RleTreeTrait> Iterator for Iter<'tree, T, A> { + type Item = SafeCursor<'tree, T, A>; fn next(&mut self) -> Option { self.cursor?; @@ -184,8 +184,8 @@ impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Iterator for Iter<'tree, ' } } -impl<'tree, 'bump: 'tree, T: Rle, A: RleTreeTrait> Iterator for IterMut<'tree, 'bump, T, A> { - type Item = SafeCursorMut<'tree, 'bump, T, A>; +impl<'tree, T: Rle, A: RleTreeTrait> Iterator for IterMut<'tree, T, A> { + type Item = SafeCursorMut<'tree, T, A>; fn next(&mut self) -> Option { self.cursor?; diff --git a/crates/rle/src/rle_tree/node/leaf_impl.rs b/crates/rle/src/rle_tree/node/leaf_impl.rs index 1a302eea..60ae8c1b 100644 --- a/crates/rle/src/rle_tree/node/leaf_impl.rs +++ b/crates/rle/src/rle_tree/node/leaf_impl.rs @@ -50,7 +50,7 @@ impl<'bump, T: Rle, A: RleTreeTrait> LeafNode<'bump, T, A> { } #[inline] - pub fn get_cursor<'tree>(&'tree self, pos: A::Int) -> SafeCursor<'tree, 'bump, T, A> { + pub fn get_cursor<'tree>(&'tree self, pos: A::Int) -> SafeCursor<'bump, T, A> { let result = A::find_pos_leaf(self, pos); assert!(result.found); // SAFETY: result.found is true @@ -66,7 +66,7 @@ impl<'bump, T: Rle, A: RleTreeTrait> LeafNode<'bump, T, A> { } #[inline] - pub fn get_cursor_mut<'b>(&'b mut self, pos: A::Int) -> SafeCursorMut<'b, 'bump, T, A> { + pub fn get_cursor_mut<'b>(&'b mut self, pos: A::Int) -> SafeCursorMut<'bump, T, A> { let result = A::find_pos_leaf(self, pos); assert!(result.found); // SAFETY: result.found is true