mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-23 05:24:51 +00:00
perf: remove len field in yspan
This commit is contained in:
parent
e3ad3e017d
commit
2c29165ae8
6 changed files with 42 additions and 35 deletions
|
@ -18,6 +18,12 @@ impl Default for ListSlice {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Range<u32>> for ListSlice {
|
||||
fn from(a: Range<u32>) -> Self {
|
||||
ListSlice::Slice(a)
|
||||
}
|
||||
}
|
||||
|
||||
impl ListSlice {
|
||||
#[inline(always)]
|
||||
pub fn from_range(range: Range<u32>) -> ListSlice {
|
||||
|
|
|
@ -72,7 +72,6 @@ impl Tracker {
|
|||
origin_right: None,
|
||||
id: ID::unknown(0),
|
||||
status: Status::new(),
|
||||
len: init_len as usize,
|
||||
slice: ListSlice::Unknown(init_len as usize),
|
||||
},
|
||||
&mut make_notify(&mut id_to_cursor),
|
||||
|
@ -114,7 +113,7 @@ impl Tracker {
|
|||
let id_span = IdSpan::new(
|
||||
yspan.id.client_id,
|
||||
yspan.id.counter,
|
||||
yspan.len as Counter + yspan.id.counter,
|
||||
yspan.atom_len() as Counter + yspan.id.counter,
|
||||
);
|
||||
let mut len = 0;
|
||||
for marker in self
|
||||
|
@ -126,7 +125,7 @@ impl Tracker {
|
|||
}
|
||||
}
|
||||
|
||||
assert_eq!(len, yspan.len);
|
||||
assert_eq!(len, yspan.atom_len());
|
||||
}
|
||||
|
||||
self.content.debug_check();
|
||||
|
|
|
@ -31,7 +31,6 @@ impl ContentMap {
|
|||
origin_left: left,
|
||||
origin_right: right,
|
||||
id,
|
||||
len,
|
||||
status: Default::default(),
|
||||
slice,
|
||||
}
|
||||
|
|
|
@ -91,10 +91,10 @@ impl Marker {
|
|||
if child.overlap(id_span) {
|
||||
let start_counter = child.id.counter;
|
||||
let offset = std::cmp::max(id_span.counter.min() - start_counter, 0);
|
||||
debug_assert!((offset as usize) < child.len);
|
||||
debug_assert!((offset as usize) < child.atom_len());
|
||||
let max_offset = std::cmp::min(
|
||||
id_span.counter.max() - start_counter,
|
||||
(child.len - 1) as i32,
|
||||
(child.atom_len() - 1) as i32,
|
||||
);
|
||||
let len = max_offset - offset + 1;
|
||||
// SAFETY: we just checked it is valid
|
||||
|
@ -103,7 +103,7 @@ impl Marker {
|
|||
*ptr,
|
||||
i,
|
||||
offset as usize,
|
||||
Position::from_offset(offset as isize, child.len),
|
||||
Position::from_offset(offset as isize, child.atom_len()),
|
||||
len as usize,
|
||||
))
|
||||
})
|
||||
|
|
|
@ -68,7 +68,6 @@ impl Status {
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct YSpan {
|
||||
pub id: ID,
|
||||
pub len: usize,
|
||||
pub status: Status,
|
||||
pub origin_left: Option<ID>,
|
||||
pub origin_right: Option<ID>,
|
||||
|
@ -76,6 +75,11 @@ pub struct YSpan {
|
|||
pub slice: ListSlice,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn y_span_size() {
|
||||
println!("{}", std::mem::size_of::<YSpan>());
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum StatusChange {
|
||||
SetAsCurrent,
|
||||
|
@ -92,7 +96,7 @@ impl YSpan {
|
|||
/// this is the last id of the span, which is **included** by self
|
||||
#[inline]
|
||||
pub fn last_id(&self) -> ID {
|
||||
self.id.inc(self.len as i32 - 1)
|
||||
self.id.inc(self.atom_len() as i32 - 1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -104,7 +108,7 @@ impl YSpan {
|
|||
pub fn contain_id(&self, id: ID) -> bool {
|
||||
self.id.client_id == id.client_id
|
||||
&& self.id.counter <= id.counter
|
||||
&& id.counter < self.id.counter + self.len as i32
|
||||
&& id.counter < self.id.counter + self.atom_len() as i32
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -113,7 +117,8 @@ impl YSpan {
|
|||
return false;
|
||||
}
|
||||
|
||||
self.id.counter < id.ctr_end() && self.id.counter + (self.len as Counter) > id.ctr_start()
|
||||
self.id.counter < id.ctr_end()
|
||||
&& self.id.counter + (self.atom_len() as Counter) > id.ctr_start()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,15 +126,14 @@ impl Mergable for YSpan {
|
|||
fn is_mergable(&self, other: &Self, _: &()) -> bool {
|
||||
other.id.client_id == self.id.client_id
|
||||
&& self.status == other.status
|
||||
&& self.id.counter + self.len as Counter == other.id.counter
|
||||
&& self.id.counter + self.atom_len() as Counter == other.id.counter
|
||||
&& self.origin_right == other.origin_right
|
||||
&& Some(self.id.inc(self.len as Counter - 1)) == other.origin_left
|
||||
&& Some(self.id.inc(self.atom_len() as Counter - 1)) == other.origin_left
|
||||
&& self.slice.is_mergable(&other.slice, &())
|
||||
}
|
||||
|
||||
fn merge(&mut self, other: &Self, _: &()) {
|
||||
self.origin_right = other.origin_right;
|
||||
self.len += other.len;
|
||||
self.slice.merge(&other.slice, &())
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +156,6 @@ impl Sliceable for YSpan {
|
|||
origin_left,
|
||||
origin_right,
|
||||
id: self.id.inc(from as i32),
|
||||
len: to - from,
|
||||
status: self.status.clone(),
|
||||
slice: self.slice.slice(from, to),
|
||||
}
|
||||
|
@ -166,24 +169,25 @@ impl InsertContentTrait for YSpan {
|
|||
}
|
||||
|
||||
impl HasLength for YSpan {
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn content_len(&self) -> usize {
|
||||
if self.status.is_activated() {
|
||||
self.len
|
||||
self.slice.atom_len()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn atom_len(&self) -> usize {
|
||||
self.len
|
||||
self.slice.atom_len()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, features = "fuzzing"))]
|
||||
pub mod test {
|
||||
use crate::{
|
||||
container::text::text_content::ListSlice,
|
||||
op::{InsertContent, OpContent},
|
||||
ContentType, Op, ID,
|
||||
};
|
||||
|
@ -201,9 +205,8 @@ pub mod test {
|
|||
origin_left: Some(ID::new(0, 0)),
|
||||
origin_right: None,
|
||||
id: ID::new(0, 1),
|
||||
len: 1,
|
||||
status: Default::default(),
|
||||
slice: Default::default(),
|
||||
slice: ListSlice::Unknown(1),
|
||||
})),
|
||||
},
|
||||
5,
|
||||
|
@ -215,9 +218,8 @@ pub mod test {
|
|||
origin_left: Some(ID::new(0, 1)),
|
||||
origin_right: None,
|
||||
id: ID::new(0, 2),
|
||||
len: 1,
|
||||
status: Default::default(),
|
||||
slice: Default::default(),
|
||||
slice: ListSlice::Unknown(1),
|
||||
})),
|
||||
},
|
||||
5,
|
||||
|
@ -239,9 +241,8 @@ pub mod test {
|
|||
origin_left: Some(ID::new(0, 0)),
|
||||
origin_right: None,
|
||||
id: ID::new(0, 1),
|
||||
len: 4,
|
||||
status: Default::default(),
|
||||
slice: Default::default(),
|
||||
slice: ListSlice::Unknown(4),
|
||||
})),
|
||||
},
|
||||
5,
|
||||
|
@ -253,9 +254,8 @@ pub mod test {
|
|||
origin_left: Some(ID::new(0, 0)),
|
||||
origin_right: Some(ID::new(0, 1)),
|
||||
id: ID::new(0, 5),
|
||||
len: 4,
|
||||
status: Default::default(),
|
||||
slice: Default::default(),
|
||||
slice: ListSlice::Unknown(4),
|
||||
})),
|
||||
},
|
||||
5,
|
||||
|
|
|
@ -5,6 +5,7 @@ use crdt_list::{
|
|||
use rle::{
|
||||
range_map::{RangeMap, WithStartEnd},
|
||||
rle_tree::{iter::IterMut, SafeCursorMut},
|
||||
HasLength,
|
||||
};
|
||||
|
||||
use crate::id::{Counter, ID};
|
||||
|
@ -27,7 +28,7 @@ impl OpSet<YSpan, ID> for OpSpanSet {
|
|||
value.id.into(),
|
||||
WithStartEnd {
|
||||
start: value.id.into(),
|
||||
end: value.id.inc(value.len as i32).into(),
|
||||
end: value.id.inc(value.atom_len() as i32).into(),
|
||||
value: true,
|
||||
},
|
||||
)
|
||||
|
@ -92,7 +93,7 @@ impl ListCrdt for YataImpl {
|
|||
}
|
||||
|
||||
fn contains(op: &Self::OpUnit, id: Self::OpId) -> bool {
|
||||
op.id.contains(op.len as Counter, id)
|
||||
op.id.contains(op.atom_len() as Counter, id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +135,10 @@ mod test {
|
|||
use crdt_list::crdt::OpSet;
|
||||
|
||||
use crate::{
|
||||
container::text::tracker::y_span::{Status, YSpan},
|
||||
container::text::{
|
||||
text_content::ListSlice,
|
||||
tracker::y_span::{Status, YSpan},
|
||||
},
|
||||
id::ID,
|
||||
};
|
||||
|
||||
|
@ -145,11 +149,10 @@ mod test {
|
|||
let mut set = OpSpanSet::default();
|
||||
set.insert(&YSpan {
|
||||
id: ID::new(1, 10),
|
||||
len: 10,
|
||||
origin_left: Some(ID::new(0, 1)),
|
||||
origin_right: Some(ID::new(0, 2)),
|
||||
status: Status::new(),
|
||||
slice: Default::default(),
|
||||
slice: ListSlice::Unknown(10),
|
||||
});
|
||||
assert!(set.contain(ID::new(1, 10)));
|
||||
assert!(set.contain(ID::new(1, 11)));
|
||||
|
@ -173,7 +176,7 @@ pub mod fuzz {
|
|||
fn fields(&self) -> Vec<std::borrow::Cow<'_, str>> {
|
||||
vec![
|
||||
self.id.to_string().into(),
|
||||
self.len.to_string().into(),
|
||||
self.atom_len().to_string().into(),
|
||||
self.status.future.to_string().into(),
|
||||
self.status.delete_times.to_string().into(),
|
||||
self.status.undo_times.to_string().into(),
|
||||
|
@ -202,7 +205,7 @@ pub mod fuzz {
|
|||
}
|
||||
|
||||
use crdt_list::test::{Action, TestFramework};
|
||||
use rle::{RleVecWithIndex, RleVecWithLen};
|
||||
use rle::{HasLength, RleVecWithIndex, RleVecWithLen};
|
||||
use tabled::TableIteratorExt;
|
||||
|
||||
use crate::{
|
||||
|
@ -221,7 +224,7 @@ pub mod fuzz {
|
|||
|
||||
impl TestFramework for YataImpl {
|
||||
fn integrate(container: &mut Self::Container, op: Self::OpUnit) {
|
||||
container.head_vv.set_end(op.id.inc(op.len as i32));
|
||||
container.head_vv.set_end(op.id.inc(op.atom_len() as i32));
|
||||
// SAFETY: we know this is safe because in [YataImpl::insert_after] there is no access to shared elements
|
||||
unsafe { crdt_list::yata::integrate::<Self>(container, op) };
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue