mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-22 12:57:20 +00:00
fix: checkout diff-calc cache issue
This commit is contained in:
parent
5688a017d6
commit
37ed452bc5
2 changed files with 218 additions and 55 deletions
|
@ -11408,11 +11408,223 @@ fn gc_fuzz_25() {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gc_fuzz_unknown() {
|
||||
test_multi_sites(
|
||||
5,
|
||||
vec![FuzzTarget::All],
|
||||
&mut [
|
||||
Handle {
|
||||
site: 1,
|
||||
target: 1,
|
||||
container: 1,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(690563377),
|
||||
bool: true,
|
||||
key: 690563369,
|
||||
pos: 2965947086361143593,
|
||||
length: 2965947086361141289,
|
||||
prop: 6714067876240238889,
|
||||
}),
|
||||
},
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(690563337),
|
||||
bool: true,
|
||||
key: 690563369,
|
||||
pos: 2965947086361143593,
|
||||
length: 2965947086361143593,
|
||||
prop: 18377265011222980905,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(690563369),
|
||||
bool: true,
|
||||
key: 690563369,
|
||||
pos: 2965947086361143593,
|
||||
length: 18446472671121713449,
|
||||
prop: 1297036692682702847,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(690563369),
|
||||
bool: true,
|
||||
key: 690563369,
|
||||
pos: 2965947086361143593,
|
||||
length: 2965937190756493609,
|
||||
prop: 720339722163530025,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 93,
|
||||
target: 0,
|
||||
container: 0,
|
||||
action: Generic(GenericAction {
|
||||
value: Container(Tree),
|
||||
bool: false,
|
||||
key: 690563328,
|
||||
pos: 2965947086361143593,
|
||||
length: 2317428740019792169,
|
||||
prop: 2956940423977314601,
|
||||
}),
|
||||
},
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 93,
|
||||
action: Generic(GenericAction {
|
||||
value: Container(Unknown(255)),
|
||||
bool: true,
|
||||
key: 4294967295,
|
||||
pos: 11457157452018352127,
|
||||
length: 18446743655463952030,
|
||||
prop: 18446744073709551615,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 52,
|
||||
target: 0,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(690563337),
|
||||
bool: true,
|
||||
key: 690563369,
|
||||
pos: 2965947086361143593,
|
||||
length: 2965947086361143593,
|
||||
prop: 18446743150982146345,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(0),
|
||||
bool: false,
|
||||
key: 690563456,
|
||||
pos: 2965947086361143593,
|
||||
length: 2965947086360553769,
|
||||
prop: 18446743017133517097,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(0),
|
||||
bool: false,
|
||||
key: 0,
|
||||
pos: 2965901829600182272,
|
||||
length: 2965947086361143593,
|
||||
prop: 2965947086361143593,
|
||||
}),
|
||||
},
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 32,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: Container(Map),
|
||||
bool: true,
|
||||
key: 690563369,
|
||||
pos: 2965947309699442985,
|
||||
length: 18446744073709551615,
|
||||
prop: 18446539564546785279,
|
||||
}),
|
||||
},
|
||||
SyncAllUndo {
|
||||
site: 158,
|
||||
op_len: 4294942366,
|
||||
},
|
||||
SyncAll,
|
||||
Checkout {
|
||||
site: 0,
|
||||
to: 690563369,
|
||||
},
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(690563369),
|
||||
bool: true,
|
||||
key: 690563369,
|
||||
pos: 2965947086361143593,
|
||||
length: 18446744073709496617,
|
||||
prop: 18446744073709551615,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 41,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(690563369),
|
||||
bool: true,
|
||||
key: 690563369,
|
||||
pos: 2965947086361143593,
|
||||
length: 3467816969836243241,
|
||||
prop: 2965911901989054761,
|
||||
}),
|
||||
},
|
||||
SyncAll,
|
||||
Handle {
|
||||
site: 41,
|
||||
target: 41,
|
||||
container: 32,
|
||||
action: Generic(GenericAction {
|
||||
value: I32(690563369),
|
||||
bool: true,
|
||||
key: 4294967049,
|
||||
pos: 3026418949592973311,
|
||||
length: 19203147547879721,
|
||||
prop: 0,
|
||||
}),
|
||||
},
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn minify() {
|
||||
minify_error(
|
||||
5,
|
||||
|n, actions| test_multi_sites_with_gc(n, vec![FuzzTarget::All], actions),
|
||||
|n, actions| test_multi_sites(n, vec![FuzzTarget::All], actions),
|
||||
|_, actions| actions.to_vec(),
|
||||
vec![],
|
||||
)
|
||||
|
|
|
@ -65,7 +65,7 @@ enum DiffCalculatorRetainMode {
|
|||
/// The diff calculator can only be used once.
|
||||
Once { used: bool },
|
||||
/// The diff calculator will be persisted and can be reused after the diff calc is done.
|
||||
Persist { recorded_ops_range: VersionRange },
|
||||
Persist,
|
||||
}
|
||||
|
||||
/// This mode defines how the diff is calculated and how it should be applied on the state.
|
||||
|
@ -121,9 +121,7 @@ impl DiffCalculator {
|
|||
Self {
|
||||
calculators: Default::default(),
|
||||
retain_mode: if persist {
|
||||
DiffCalculatorRetainMode::Persist {
|
||||
recorded_ops_range: Default::default(),
|
||||
}
|
||||
DiffCalculatorRetainMode::Persist
|
||||
} else {
|
||||
DiffCalculatorRetainMode::Once { used: false }
|
||||
},
|
||||
|
@ -151,7 +149,6 @@ impl DiffCalculator {
|
|||
let s = tracing::span!(tracing::Level::INFO, "DiffCalc", ?before, ?after,);
|
||||
let _e = s.enter();
|
||||
|
||||
let mut use_persisted_shortcut = false;
|
||||
let mut merged = before.clone();
|
||||
merged.merge(after);
|
||||
let (lca, mut diff_mode, iter) =
|
||||
|
@ -162,34 +159,15 @@ impl DiffCalculator {
|
|||
panic!("DiffCalculator with retain_mode Once can only be used once");
|
||||
}
|
||||
}
|
||||
DiffCalculatorRetainMode::Persist { recorded_ops_range } => {
|
||||
if recorded_ops_range.contains_ops_between(&lca, &merged)
|
||||
&& recorded_ops_range.contains_ops_between(before, after)
|
||||
{
|
||||
use_persisted_shortcut = true;
|
||||
} else {
|
||||
DiffCalculatorRetainMode::Persist => {
|
||||
diff_mode = DiffMode::Checkout;
|
||||
recorded_ops_range.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let affected_set = if !use_persisted_shortcut {
|
||||
let affected_set = {
|
||||
tracing::debug!("LCA: {:?} mode={:?}", &lca, diff_mode);
|
||||
let mut started_set = FxHashSet::default();
|
||||
for (change, (start_counter, end_counter), vv) in iter {
|
||||
if let DiffCalculatorRetainMode::Persist { recorded_ops_range } =
|
||||
&mut self.retain_mode
|
||||
{
|
||||
if container_filter.is_none() {
|
||||
recorded_ops_range.extends_to_include_id_span(IdSpan::new(
|
||||
change.peer(),
|
||||
start_counter,
|
||||
end_counter,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let iter_start = change
|
||||
.ops
|
||||
.binary_search_by(|op| op.ctr_last().cmp(&start_counter))
|
||||
|
@ -253,33 +231,6 @@ impl DiffCalculator {
|
|||
}
|
||||
|
||||
Some(started_set)
|
||||
} else {
|
||||
debug!("Use persisted shortcut");
|
||||
// We can calculate the diff by the current calculators.
|
||||
|
||||
// Find a set of affected containers idx, if it's relatively cheap
|
||||
if before.distance_between(after) < self.calculators.len() || cfg!(debug_assertions) {
|
||||
let mut set = FxHashSet::default();
|
||||
oplog.for_each_change_within(before, after, |change, (start, end)| {
|
||||
for op in change.ops.iter() {
|
||||
if op.ctr_end() <= start || op.ctr_start() >= end {
|
||||
continue;
|
||||
}
|
||||
|
||||
let idx = op.container;
|
||||
if let Some(filter) = container_filter {
|
||||
if !filter(idx) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
set.insert(op.container);
|
||||
}
|
||||
});
|
||||
Some(set)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
// Because we need to get correct `bring_back` value that indicates container is created during this round of diff calc,
|
||||
|
|
Loading…
Reference in a new issue