mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-08 21:47:41 +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]
|
#[test]
|
||||||
fn minify() {
|
fn minify() {
|
||||||
minify_error(
|
minify_error(
|
||||||
5,
|
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(),
|
|_, actions| actions.to_vec(),
|
||||||
vec![],
|
vec![],
|
||||||
)
|
)
|
||||||
|
|
|
@ -65,7 +65,7 @@ enum DiffCalculatorRetainMode {
|
||||||
/// The diff calculator can only be used once.
|
/// The diff calculator can only be used once.
|
||||||
Once { used: bool },
|
Once { used: bool },
|
||||||
/// The diff calculator will be persisted and can be reused after the diff calc is done.
|
/// 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.
|
/// This mode defines how the diff is calculated and how it should be applied on the state.
|
||||||
|
@ -121,9 +121,7 @@ impl DiffCalculator {
|
||||||
Self {
|
Self {
|
||||||
calculators: Default::default(),
|
calculators: Default::default(),
|
||||||
retain_mode: if persist {
|
retain_mode: if persist {
|
||||||
DiffCalculatorRetainMode::Persist {
|
DiffCalculatorRetainMode::Persist
|
||||||
recorded_ops_range: Default::default(),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
DiffCalculatorRetainMode::Once { used: false }
|
DiffCalculatorRetainMode::Once { used: false }
|
||||||
},
|
},
|
||||||
|
@ -151,7 +149,6 @@ impl DiffCalculator {
|
||||||
let s = tracing::span!(tracing::Level::INFO, "DiffCalc", ?before, ?after,);
|
let s = tracing::span!(tracing::Level::INFO, "DiffCalc", ?before, ?after,);
|
||||||
let _e = s.enter();
|
let _e = s.enter();
|
||||||
|
|
||||||
let mut use_persisted_shortcut = false;
|
|
||||||
let mut merged = before.clone();
|
let mut merged = before.clone();
|
||||||
merged.merge(after);
|
merged.merge(after);
|
||||||
let (lca, mut diff_mode, iter) =
|
let (lca, mut diff_mode, iter) =
|
||||||
|
@ -162,34 +159,15 @@ impl DiffCalculator {
|
||||||
panic!("DiffCalculator with retain_mode Once can only be used once");
|
panic!("DiffCalculator with retain_mode Once can only be used once");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DiffCalculatorRetainMode::Persist { recorded_ops_range } => {
|
DiffCalculatorRetainMode::Persist => {
|
||||||
if recorded_ops_range.contains_ops_between(&lca, &merged)
|
|
||||||
&& recorded_ops_range.contains_ops_between(before, after)
|
|
||||||
{
|
|
||||||
use_persisted_shortcut = true;
|
|
||||||
} else {
|
|
||||||
diff_mode = DiffMode::Checkout;
|
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);
|
tracing::debug!("LCA: {:?} mode={:?}", &lca, diff_mode);
|
||||||
let mut started_set = FxHashSet::default();
|
let mut started_set = FxHashSet::default();
|
||||||
for (change, (start_counter, end_counter), vv) in iter {
|
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
|
let iter_start = change
|
||||||
.ops
|
.ops
|
||||||
.binary_search_by(|op| op.ctr_last().cmp(&start_counter))
|
.binary_search_by(|op| op.ctr_last().cmp(&start_counter))
|
||||||
|
@ -253,33 +231,6 @@ impl DiffCalculator {
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(started_set)
|
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,
|
// 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