diff --git a/.gitignore b/.gitignore index d25ee75d..06ed9fd6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target *.log flamegraph.svg +target diff --git a/crates/loro-core/fuzz/.gitignore b/crates/loro-core/fuzz/.gitignore index a0925114..1a45eee7 100644 --- a/crates/loro-core/fuzz/.gitignore +++ b/crates/loro-core/fuzz/.gitignore @@ -1,3 +1,4 @@ target corpus artifacts +coverage diff --git a/crates/loro-core/justfile b/crates/loro-core/justfile index e08f3026..ba8999c2 100644 --- a/crates/loro-core/justfile +++ b/crates/loro-core/justfile @@ -18,7 +18,7 @@ crev: cargo crev crate check fuzz: - cargo fuzz run yata -- -max_total_time=300 -max_len=1000 -jobs=2 + cargo fuzz run yata -- -max_total_time=300 -max_len=4000 -jobs=2 flame: cargo flamegraph --example test --features=fuzzing --root 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 c3c80bea..83e693f0 100644 --- a/crates/loro-core/src/container/text/tracker/content_map.rs +++ b/crates/loro-core/src/container/text/tracker/content_map.rs @@ -7,7 +7,7 @@ use rle::{ use crate::{id::ID, span::IdSpan}; -use super::y_span::{StatusChange, YSpan, YSpanTreeTrait}; +use super::y_span::{Status, StatusChange, YSpan, YSpanTreeTrait}; /// It stores all the [YSpan] data, including the deleted/undo ones /// @@ -80,22 +80,33 @@ impl ContentMap { } } - let next = if prev.is_some() { - let next_cursor = cursor.next_elem_start(); + if prev.is_some() { + let mut next_cursor = cursor.next_elem_start(); let mut ans = None; - if let Some(next_inner) = next_cursor { - let mut cursor = next_inner.unwrap(); - cursor.offset = 0; - cursor.pos = Position::Start; - ans = Some(next_inner.as_ref().id); + while let Some(next_inner) = next_cursor { + if next_inner.as_ref().status.unapplied { + let mut cursor = next_inner.unwrap(); + cursor.offset = 0; + cursor.pos = Position::Start; + ans = Some(next_inner.as_ref().id); + break; + } + + next_cursor = next_inner.next_elem_start(); } - ans + (prev, ans) } else { - Some(cursor.as_ref().id) - }; + while cursor.as_ref().status.unapplied { + if let Some(next) = cursor.next_elem_start() { + cursor = next; + } else { + return (prev, None); + } + } - (prev, next) + (prev, Some(cursor.as_ref().id)) + } } else { (None, None) } diff --git a/crates/loro-core/src/container/text/tracker/y_span.rs b/crates/loro-core/src/container/text/tracker/y_span.rs index 96bf7b57..f6a9b78b 100644 --- a/crates/loro-core/src/container/text/tracker/y_span.rs +++ b/crates/loro-core/src/container/text/tracker/y_span.rs @@ -72,7 +72,6 @@ impl YSpan { #[inline] pub fn can_be_origin(&self) -> bool { - debug_assert!(self.len > 0); self.status.is_activated() }