Skip to content

Commit

Permalink
fix: encode snapshot when detached
Browse files Browse the repository at this point in the history
  • Loading branch information
zxch3n committed Sep 25, 2024
1 parent ce690aa commit 0961874
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
23 changes: 19 additions & 4 deletions crates/loro-internal/src/encoding/fast_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ impl OpLog {
}

pub(crate) fn encode_snapshot<W: std::io::Write>(doc: &LoroDoc, w: &mut W) {
// events should be emitted before encode snapshot
assert!(doc.drop_pending_events().is_empty());
let old_state_frontiers = doc.state_frontiers();
let was_detached = doc.is_detached();
let mut state = doc.app_state().try_lock().unwrap();
let oplog = doc.oplog().try_lock().unwrap();
let is_gc = state.store.gc_store().is_some();
Expand All @@ -169,18 +173,23 @@ pub(crate) fn encode_snapshot<W: std::io::Write>(doc: &LoroDoc, w: &mut W) {
return;
}
assert!(!state.is_in_txn());
assert_eq!(oplog.frontiers(), &state.frontiers);

let oplog_bytes = oplog.encode_change_store();
state.ensure_all_alive_containers();

if oplog.is_trimmed() {
assert_eq!(
oplog.trimmed_frontiers(),
state.store.trimmed_frontiers().unwrap()
);
}

if was_detached {
let latest = oplog.frontiers().clone();
drop(oplog);
drop(state);
doc.checkout_without_emitting(&latest).unwrap();
state = doc.app_state().try_lock().unwrap();
}

state.ensure_all_alive_containers();
let state_bytes = state.store.encode();
_encode_snapshot(
Snapshot {
Expand All @@ -190,6 +199,12 @@ pub(crate) fn encode_snapshot<W: std::io::Write>(doc: &LoroDoc, w: &mut W) {
},
w,
);

if was_detached {
drop(state);
doc.checkout_without_emitting(&old_state_frontiers).unwrap();
doc.drop_pending_events();
}
}

pub(crate) fn encode_snapshot_at<W: std::io::Write>(
Expand Down
10 changes: 4 additions & 6 deletions crates/loro-internal/src/loro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use crate::{
undo::DiffBatch,
utils::subscription::{SubscriberSet, Subscription},
version::{shrink_frontiers, Frontiers, ImVersionVector},
HandlerTrait, InternalString, ListHandler, LoroError, MapHandler, VersionVector,
DocDiff, HandlerTrait, InternalString, ListHandler, LoroError, MapHandler, VersionVector,
};

pub use crate::encoding::ExportMode;
Expand Down Expand Up @@ -546,11 +546,9 @@ impl LoroDoc {
}
}

pub(crate) fn drop_pending_events(&self) {
let _events = {
let mut state = self.state.lock().unwrap();
state.take_events()
};
pub(crate) fn drop_pending_events(&self) -> Vec<DocDiff> {
let mut state = self.state.lock().unwrap();
state.take_events()
}

#[instrument(skip_all)]
Expand Down
18 changes: 18 additions & 0 deletions crates/loro/tests/loro_rust_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1729,3 +1729,21 @@ fn change_peer_id() {
doc.set_peer_id(4).unwrap();
assert_eq!(received_peer_id.load(Ordering::SeqCst), 3);
}

#[test]
fn test_encode_snapshot_when_checkout() {
let doc = LoroDoc::new();
doc.get_text("text").insert(0, "Hello").unwrap();
doc.commit();
let f = doc.state_frontiers();
doc.get_text("text").insert(5, " World").unwrap();
doc.commit();
doc.checkout(&f).unwrap();
let snapshot = doc.export(loro::ExportMode::snapshot());
let new_doc = LoroDoc::new();
new_doc.import(&snapshot).unwrap();
assert_eq!(
new_doc.get_deep_value().to_json_value(),
json!({"text": "Hello World"})
);
}

0 comments on commit 0961874

Please sign in to comment.