chore: bk

This commit is contained in:
Zixuan Chen 2022-10-25 18:11:12 +08:00
parent 352ddc1c11
commit e2dc6382d0
7 changed files with 105 additions and 23 deletions

View file

@ -46,6 +46,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -257,6 +263,7 @@ name = "loro-core"
version = "0.1.0"
dependencies = [
"arbitrary",
"bit-vec",
"colored",
"crdt-list",
"enum-as-inner",

View file

@ -167,11 +167,8 @@ impl Container for TextContainer {
// stage 1
// TODO: need a better mechanism to track the head (KEEP IT IN TRACKER?)
let path = store.find_path(&head, &latest_head);
dbg!(&path);
debug_log!("path={:?}", &path.right);
for iter in store.iter_partial(&head, path.right) {
dbg!(&iter);
self.tracker.retreat(&iter.retreat);
self.tracker.forward(&iter.forward);
// TODO: avoid this clone
let change = iter
.data
@ -182,6 +179,8 @@ impl Container for TextContainer {
format!("{:?}", &iter.forward).red(),
format!("{:#?}", &change).blue(),
);
self.tracker.retreat(&iter.retreat);
self.tracker.forward(&iter.forward);
for op in change.ops.iter() {
if op.container == self.id {
// TODO: convert op to local

View file

@ -247,7 +247,6 @@ impl Tracker {
slice.clone(),
);
debug_log!("INSERT YSPAN={}", format!("{:#?}", &yspan).red());
dbg!(&self.content);
// SAFETY: we know this is safe because in [YataImpl::insert_after] there is no access to shared elements
unsafe { crdt_list::yata::integrate::<YataImpl>(self, yspan) };
}

View file

@ -8,11 +8,11 @@
//!
use std::{
collections::{BinaryHeap, HashMap},
fmt::Debug,
time::Instant,
fmt::{format, Debug},
};
use bit_vec::BitVec;
use colored::Colorize;
use fxhash::{FxHashMap, FxHashSet};
use rle::{HasLength, Sliceable};
use smallvec::SmallVec;
@ -23,6 +23,7 @@ mod test;
use crate::{
change::Lamport,
debug_log,
id::{ClientID, Counter, ID},
span::{HasId, HasIdSpan, HasLamport, HasLamportSpan, IdSpan},
version::{IdSpanVector, VersionVector, VersionVectorDiff},
@ -113,12 +114,16 @@ impl<T: Dag + ?Sized> DagUtils for T {
fn find_path(&self, from: &[ID], to: &[ID]) -> VersionVectorDiff {
let mut ans = VersionVectorDiff::default();
debug_log!(
"{}",
format!("FINDPATH from={:?} to={:?}", from, to).green()
);
_find_common_ancestor(
&|v| self.get(v),
from,
to,
&mut |span, node_type| {
// dbg!(span, node_type);
dbg!(span, node_type);
match node_type {
NodeType::A => ans.merge_left(span),
NodeType::B => ans.merge_right(span),
@ -131,6 +136,7 @@ impl<T: Dag + ?Sized> DagUtils for T {
true,
);
// dbg!(from, to, &ans);
ans
}
@ -291,6 +297,10 @@ where
D: DagNode + 'a,
F: Fn(ID) -> Option<&'a D>,
{
if a_id.is_empty() || b_id.is_empty() {
return smallvec::smallvec![];
}
let mut ids = Vec::with_capacity(a_id.len() + b_id.len());
for id in a_id {
ids.push(*id);
@ -484,7 +494,7 @@ fn update_frontier(frontier: &mut Vec<ID>, new_node_id: ID, new_node_deps: &[ID]
}
}
// TODO: BitVec may be too slow here
// TODO: need bench, BitVec may be slow here
fn _find_common_ancestor_new<'a, F, D>(get: &'a F, ids: &[ID]) -> FxHashMap<ClientID, Counter>
where
D: DagNode + 'a,
@ -522,6 +532,7 @@ where
if this_node.id_span() == other_node.id_span() {
if other_map.all() {
shared_num -= 1;
is_shared = true;
}
if !is_shared && this_map.or(other_map) && this_map.all() {
@ -542,6 +553,7 @@ where
is_shared = true;
} else if !is_shared && visited_map.or(&this_map) && visited_map.all() {
ans.insert(this_node.id.client_id, this_node.id_last().counter);
this_map.set_all();
is_shared = true;
}
} else {
@ -575,14 +587,13 @@ where
if is_shared {
shared_num += this_node.deps.len()
}
if !is_shared {
} else {
if queue.is_empty() {
ans.clear();
break;
}
// TODO: simplify this logic
if this_node.deps.is_empty() {
if this_node.len == 1 {
ans.clear();

View file

@ -271,13 +271,18 @@ impl<'a, T: DagNode + 'a, D: Dag<Node = T>> Iterator for DagPartialIter<'a, D> {
});
}
dbg!(&node);
let deps: SmallVec<[_; 2]> = if slice_from == 0 {
println!("000");
node.deps().iter().copied().collect()
} else {
println!("111");
smallvec::smallvec![node.id_start().inc(slice_from - 1)]
};
dbg!(&self.frontier, &deps);
let path = self.dag.find_path(&self.frontier, &deps);
dbg!(&self.frontier);
dbg!(&deps);
dbg!(&path);
// NOTE: we expect user to update the tracker, to apply node, after visiting the node
self.frontier = smallvec::smallvec![node.id_start().inc(slice_end - 1)];
Some(IterReturn {

View file

@ -747,22 +747,16 @@ mod find_common_ancestors {
let mut a2 = TestDag::new(2);
a0.push(3);
a1.merge(&a0);
a2.merge(&a0);
a1.push(3);
a2.push(2);
a2.merge(&a0);
a2.push(1);
a1.merge(&a2);
a2.push(1);
a1.push(1);
a1.merge(&a2);
a1.push(1);
a1.nodes
.get_mut(&1)
.unwrap()
.last_mut()
.unwrap()
.deps
.push(ID::new(0, 1));
a0.push(1);
a1.merge(&a2);
a1.merge(&a0);
@ -771,7 +765,7 @@ mod find_common_ancestors {
a1.find_common_ancestor(&[ID::new(0, 3)], &[ID::new(1, 4)])
.first()
.copied(),
None
Some(ID::new(0, 2))
);
assert_eq!(
a1.find_common_ancestor(&[ID::new(2, 3)], &[ID::new(1, 3)])
@ -870,6 +864,31 @@ mod find_common_ancestors_proptest {
}
}
#[test]
fn issue_1() {
test_single_common_ancestor(
2,
vec![
Interaction {
dag_idx: 1,
merge_with: None,
len: 1,
},
Interaction {
dag_idx: 0,
merge_with: None,
len: 1,
},
],
vec![Interaction {
dag_idx: 0,
merge_with: None,
len: 1,
}],
)
.unwrap();
}
fn test_single_common_ancestor(
dag_num: i32,
mut before_merge_insertion: Vec<Interaction>,
@ -911,10 +930,11 @@ mod find_common_ancestors_proptest {
let (dag0, dag1) = array_mut_ref!(&mut dags, [0, 1]);
dag1.push(1);
dag0.merge(dag1);
// println!("{}", dag0.mermaid());
let a = dags[0].nodes.get(&0).unwrap().last().unwrap().id_last();
let b = dags[1].nodes.get(&1).unwrap().last().unwrap().id_last();
let actual = dags[0].find_common_ancestor(&[a], &[b]);
prop_assert_eq!(actual.first().copied().unwrap(), expected);
prop_assert_eq!(&*actual, &[expected]);
Ok(())
}

View file

@ -306,6 +306,47 @@ mod test {
use super::Action::*;
use super::*;
#[test]
fn test_11() {
test_multi_sites(
2,
vec![
Ins {
content: "?\0\u{1}\0\u{18}\0".into(),
pos: 727894294070016698,
site: 248,
},
Ins {
content: "\u{10}".into(),
pos: 16153481340371206368,
site: 33,
},
Sync { from: 177, to: 0 },
Ins {
content: "\n".into(),
pos: 9189030930189130488,
site: 0,
},
Ins {
content: "\u{13}\u{b}\u{1}\0\n\0\n".into(),
pos: 9655420767302589176,
site: 127,
},
Sync { from: 10, to: 19 },
Ins {
content: "\0".into(),
pos: 1374708439171007232,
site: 19,
},
Ins {
content: "\0".into(),
pos: 93,
site: 0,
},
],
)
}
#[test]
fn test_10() {
test_multi_sites(