fix: export snapshot error on a gc doc

This commit is contained in:
Zixuan Chen 2024-09-19 11:08:34 +08:00
parent e592d4f830
commit 1ea2a24d74
No known key found for this signature in database
8 changed files with 180 additions and 19 deletions

View file

@ -536,6 +536,7 @@ dependencies = [
"either",
"enum-as-inner 0.6.0",
"generic-btree",
"loro-common 0.16.12",
"loro-delta 0.16.12",
"loro-internal 0.16.12",
"loro-kv-store",
@ -586,6 +587,7 @@ dependencies = [
"nonmax",
"serde",
"serde_columnar",
"serde_json",
"string_cache",
"thiserror",
]

View file

@ -227,6 +227,7 @@ impl Actor {
match self.loro.checkout(&f) {
Ok(_) => {
// check snapshot correctness after checkout
self.loro.check_state_correctness_slow();
self.loro.checkout_to_latest();
let new_doc = LoroDoc::new();
new_doc

View file

@ -10784,6 +10784,170 @@ fn gc_fuzz_20() {
)
}
#[test]
fn gc_fuzz_21() {
test_multi_sites_with_gc(
5,
vec![FuzzTarget::All],
&mut [
Handle {
site: 11,
target: 11,
container: 11,
action: Generic(GenericAction {
value: I32(185335563),
bool: true,
key: 3385444809,
pos: 5714873654208057167,
length: 5714873654208057137,
prop: 5714873654208057167,
}),
},
Checkout {
site: 79,
to: 189747023,
},
Handle {
site: 11,
target: 38,
container: 11,
action: Generic(GenericAction {
value: Container(Map),
bool: true,
key: 185274159,
pos: 795741901218843403,
length: 795741901218843403,
prop: 795741901218843403,
}),
},
Handle {
site: 11,
target: 11,
container: 11,
action: Generic(GenericAction {
value: Container(List),
bool: true,
key: 189747023,
pos: 2748896764614085387,
length: 3400217718631893771,
prop: 795741901219114799,
}),
},
Handle {
site: 11,
target: 11,
container: 11,
action: Generic(GenericAction {
value: I32(185273099),
bool: true,
key: 185273099,
pos: 795741901218843549,
length: 795741901218843403,
prop: 5714873654208102155,
}),
},
Handle {
site: 11,
target: 11,
container: 11,
action: Generic(GenericAction {
value: I32(805178123),
bool: true,
key: 791613439,
pos: 795741901218843599,
length: 795741901218843403,
prop: 795741901218843403,
}),
},
Handle {
site: 11,
target: 11,
container: 11,
action: Generic(GenericAction {
value: I32(185273099),
bool: true,
key: 185273099,
pos: 795741901218843403,
length: 18446743021627837195,
prop: 795741909623504895,
}),
},
Handle {
site: 11,
target: 15,
container: 11,
action: Generic(GenericAction {
value: I32(185273099),
bool: true,
key: 1862994699,
pos: 795741901224567158,
length: 2741296940242897675,
prop: 3458764505415879435,
}),
},
Handle {
site: 11,
target: 11,
container: 11,
action: Generic(GenericAction {
value: I32(185273099),
bool: true,
key: 185273099,
pos: 795741901218843403,
length: 795741901218843403,
prop: 8001501305011637003,
}),
},
Undo {
site: 111,
op_len: 1869573999,
},
Undo {
site: 111,
op_len: 1869573999,
},
Undo {
site: 79,
op_len: 1330597711,
},
Checkout {
site: 79,
to: 1330597711,
},
Checkout {
site: 11,
to: 185273099,
},
Handle {
site: 11,
target: 11,
container: 254,
action: Generic(GenericAction {
value: I32(185544495),
bool: true,
key: 185273099,
pos: 795741901218843403,
length: 795741901218843403,
prop: 4123339075892218635,
}),
},
Handle {
site: 11,
target: 11,
container: 11,
action: Generic(GenericAction {
value: I32(1330597887),
bool: true,
key: 1330597711,
pos: 2741296940242897675,
length: 3458764505415879462,
prop: 1302123111085387567,
}),
},
],
)
}
#[test]
fn minify() {
minify_error(

View file

@ -15,7 +15,7 @@
//!
use std::io::{Read, Write};
use crate::{oplog::ChangeStore, LoroDoc, OpLog, VersionVector};
use crate::{encoding::gc, oplog::ChangeStore, LoroDoc, OpLog, VersionVector};
use bytes::{Buf, Bytes};
use loro_common::{IdSpan, LoroError, LoroResult};
use tracing::trace;
@ -161,12 +161,19 @@ impl OpLog {
pub(crate) fn encode_snapshot<W: std::io::Write>(doc: &LoroDoc, w: &mut W) {
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();
if is_gc {
let f = oplog.trimmed_frontiers().clone();
drop(oplog);
drop(state);
gc::export_gc_snapshot(doc, &f, w).unwrap();
return;
}
assert!(!state.is_in_txn());
assert_eq!(oplog.frontiers(), &state.frontiers);
let oplog_bytes = oplog.encode_change_store();
state.ensure_all_alive_containers();
let state_bytes = state.store.encode();
if oplog.is_trimmed() {
assert_eq!(
@ -175,11 +182,12 @@ pub(crate) fn encode_snapshot<W: std::io::Write>(doc: &LoroDoc, w: &mut W) {
);
}
let state_bytes = state.store.encode();
_encode_snapshot(
Snapshot {
oplog_bytes,
state_bytes: Some(state_bytes),
gc_bytes: state.store.encode_gc(),
gc_bytes: Bytes::new(),
},
w,
);

View file

@ -128,14 +128,6 @@ impl ContainerStore {
self.store.flush()
}
pub fn encode_gc(&mut self) -> Bytes {
if let Some(gc) = self.gc_store.as_mut() {
gc.store.try_lock().unwrap().get_kv().export()
} else {
Bytes::new()
}
}
pub fn trimmed_frontiers(&self) -> Option<&Frontiers> {
self.gc_store.as_ref().map(|x| &x.trimmed_frontiers)
}

View file

@ -9,12 +9,6 @@ use loro_kv_store::{mem_store::MemKvConfig, MemKvStore};
use crate::kv_store::KvStore;
pub(crate) enum Status {
BytesOnly,
ImmBoth,
MutState,
}
/// This thin wrapper aims to limit the ability to modify the kv store and make
/// it easy to find all the modifications.
pub(crate) struct KvWrapper {

View file

@ -6,7 +6,7 @@ export {
LoroMovableList, LoroText, LoroTree, LoroTreeNode, MapOp, MovableListOp,
OpId, PeerID, Side, TextOp, TreeID, TreeNodeValue, TreeOp, UndoConfig,
UndoManager, UnknownOp, Value, VersionVector, decodeImportBlobMeta, setDebug,
newContainerID, newRootContainerID
newContainerID, newRootContainerID, LoroDoc
} from "loro-wasm";
import {
Container,

View file

@ -7,7 +7,7 @@
"scripts": {
"check-all": "cargo hack check --each-feature",
"build": "cargo build",
"test": "cargo nextest run --features=test_utils && cargo test --doc",
"test": "cargo nextest run --features=test_utils --no-fail-fast && cargo test --doc",
"test-all": "nr test && nr test-wasm",
"test-wasm": "cd crates/loro-wasm && deno task dev && cd ../../loro-js && pnpm i && pnpm run test",
"coverage": "mkdir -p coverage && cargo llvm-cov nextest --features test_utils --lcov > coverage/lcov-nextest.info && cargo llvm-cov report",