diff --git a/.vscode/settings.json b/.vscode/settings.json index 92b9e7f5..960c47f7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,7 +23,9 @@ "RUST_BACKTRACE": "full", "DEBUG": "*" }, - "rust-analyzer.cargo.features": ["test_utils"], + "rust-analyzer.cargo.features": [ + // "test_utils" + ], "editor.defaultFormatter": "rust-lang.rust-analyzer", "rust-analyzer.server.extraEnv": { "RUSTUP_TOOLCHAIN": "stable" }, "editor.formatOnSave": true, @@ -41,5 +43,6 @@ "*.rs": "${capture}.excalidraw" }, "excalidraw.theme": "dark", - "deno.enable": true + "deno.enable": true, + "cortex-debug.variableUseNaturalFormat": true } diff --git a/crates/loro-internal/src/container/text/tracker.rs b/crates/loro-internal/src/container/text/tracker.rs index b662eb73..296da0d4 100644 --- a/crates/loro-internal/src/container/text/tracker.rs +++ b/crates/loro-internal/src/container/text/tracker.rs @@ -41,9 +41,27 @@ pub mod yata_impl; /// - [YSpan] never gets removed in both [ContentMap] and [CursorMap] /// - The deleted contents are marked with deleted, but still lives on the [ContentMap] with length of 0 /// + +#[cfg(not(feature = "test_utils"))] +#[derive(Default, Debug)] +pub struct Tracker { + /// from start_vv to latest vv are applied + start_vv: VersionVector, + /// latest applied ops version vector + all_vv: VersionVector, + /// current content version vector + current_vv: VersionVector, + /// The pretend current content version vector. + /// + /// Because sometimes we don't actually need to checkout to the version. + /// So we may cache the changes then applying them when we really need to. + content: ContentMap, + id_to_cursor: CursorMap, +} + +#[cfg(feature = "test_utils")] #[derive(Default, Debug)] pub struct Tracker { - #[cfg(feature = "test_utils")] client_id: PeerID, /// from start_vv to latest vv are applied start_vv: VersionVector, @@ -143,7 +161,7 @@ impl Tracker { } /// for_diff = true should be called after the tracker checkout to A version with for_diff = false. - /// Then we can calculate the diff between A and vv. + /// Then we can calculate the diff between A and vv. fn _checkout(&mut self, vv: &VersionVector, for_diff: bool) { // clear after_status as it may be outdated if for_diff { diff --git a/crates/loro-internal/src/event.rs b/crates/loro-internal/src/event.rs index 9237b062..4a4c5019 100644 --- a/crates/loro-internal/src/event.rs +++ b/crates/loro-internal/src/event.rs @@ -5,7 +5,7 @@ use smallvec::SmallVec; use crate::{ container::ContainerID, delta::{Delta, DeltaType, MapDelta, MapDiff, Meta}, - text::text_content::{SliceRanges}, + text::text_content::SliceRanges, transaction::Origin, version::Frontiers, InternalString, LoroValue, diff --git a/crates/loro-internal/src/log_store/iter.rs b/crates/loro-internal/src/log_store/iter.rs index 98c71b2f..83bab7cb 100644 --- a/crates/loro-internal/src/log_store/iter.rs +++ b/crates/loro-internal/src/log_store/iter.rs @@ -11,7 +11,6 @@ use fxhash::FxHashMap; use rle::HasLength; use rle::RleVec; - use crate::change::Change; pub struct ClientOpIter<'a> { diff --git a/crates/loro-internal/src/refactor/handler.rs b/crates/loro-internal/src/refactor/handler.rs new file mode 100644 index 00000000..e951e6ee --- /dev/null +++ b/crates/loro-internal/src/refactor/handler.rs @@ -0,0 +1,11 @@ +use crate::container::registry::ContainerIdx; + +use super::txn::Transaction; + +pub struct Text { + container_idx: ContainerIdx, +} + +impl Text { + pub fn insert(&self, txn: &Transaction, pos: usize, s: &str) {} +} diff --git a/crates/loro-internal/src/refactor/mod.rs b/crates/loro-internal/src/refactor/mod.rs index 0118a23f..3627b9af 100644 --- a/crates/loro-internal/src/refactor/mod.rs +++ b/crates/loro-internal/src/refactor/mod.rs @@ -1,6 +1,9 @@ +#![allow(dead_code)] + pub(super) mod arena; mod container; pub(super) mod diff_calc; +mod handler; pub mod oplog; mod state; mod txn; diff --git a/crates/loro-internal/src/refactor/oplog.rs b/crates/loro-internal/src/refactor/oplog.rs index 16e97f26..482d1273 100644 --- a/crates/loro-internal/src/refactor/oplog.rs +++ b/crates/loro-internal/src/refactor/oplog.rs @@ -1,9 +1,9 @@ -mod dag; +pub(crate) mod dag; use fxhash::FxHashMap; use rle::RleVec; use smallvec::SmallVec; -use tabled::measurment::Percent; +// use tabled::measurment::Percent; use crate::change::{Change, Lamport, Timestamp}; use crate::container::list::list_op::{InnerListOp, ListOp}; @@ -100,9 +100,8 @@ impl OpLog { /// # Err /// /// Return Err(LoroError::UsedOpID) when the change's id is occupied - pub fn import_change(&mut self, change: Change) -> Result<(), LoroError> { + pub fn import_change(&mut self, change: Change) -> Result<(), LoroError> { self.check_id_valid(change.id)?; - let change = self.convert_change(change); if let Err(id) = self.check_deps(&change.deps) { self.pending_changes.entry(id).or_default().push(change); return Ok(()); diff --git a/crates/loro-internal/src/refactor/state.rs b/crates/loro-internal/src/refactor/state.rs index e1c2eed9..0456b337 100644 --- a/crates/loro-internal/src/refactor/state.rs +++ b/crates/loro-internal/src/refactor/state.rs @@ -26,7 +26,7 @@ pub struct AppState { pub(super) frontiers: Frontiers, state: FxHashMap, - arena: SharedArena, + pub(super) arena: SharedArena, in_txn: bool, changed_in_txn: FxHashSet, diff --git a/crates/loro-internal/src/refactor/txn.rs b/crates/loro-internal/src/refactor/txn.rs index ae9b6f29..9525f171 100644 --- a/crates/loro-internal/src/refactor/txn.rs +++ b/crates/loro-internal/src/refactor/txn.rs @@ -1,52 +1,67 @@ +use std::sync::{Arc, Mutex}; + use rle::RleVec; -use crate::{change::Change, op::RemoteOp, LoroError}; +use crate::{change::Change, op::Op, LoroError}; -use super::{oplog::OpLog, state::AppState}; +use super::{arena::SharedArena, oplog::OpLog, state::AppState}; -pub struct Transaction<'a> { +pub struct Transaction { finished: bool, - state: &'a mut AppState, - ops: RleVec<[RemoteOp<'a>; 1]>, + state: Arc>, + ops: RleVec<[Op; 1]>, + oplog: Arc>, + arena: SharedArena, } -impl<'a> Transaction<'a> { - pub fn new(state: &'a mut AppState) -> Self { - state.start_txn(); +impl Transaction { + pub fn new(state: Arc>, oplog: Arc>) -> Self { + let mut state_lock = state.lock().unwrap(); + state_lock.start_txn(); + let arena = state_lock.arena.clone(); + drop(state_lock); Self { state, + arena, + oplog, finished: false, ops: RleVec::new(), } } pub fn abort(&mut self) { - self.state.abort_txn(); + self.state.lock().unwrap().abort_txn(); self.finished = true; } pub fn commit(&mut self, oplog: &mut OpLog) -> Result<(), LoroError> { + let mut state = self.state.lock().unwrap(); let ops = std::mem::take(&mut self.ops); let change = Change { ops, - deps: self.state.frontiers.clone(), - id: oplog.next_id(self.state.peer), + deps: state.frontiers.clone(), + id: oplog.next_id(state.peer), lamport: oplog.next_lamport(), timestamp: oplog.get_timestamp(), }; if let Err(err) = oplog.import_change(change) { + drop(state); self.abort(); return Err(err); } - self.state.commit_txn(); + state.commit_txn(); self.finished = true; Ok(()) } + + pub fn decode(&mut self, updates: &[u8]) -> Result<(), LoroError> { + unimplemented!() + } } -impl<'a> Drop for Transaction<'a> { +impl Drop for Transaction { fn drop(&mut self) { if !self.finished { self.abort();