Skip to content

Commit

Permalink
Changed ConflictGraph into a struct. Added base_version field, corres…
Browse files Browse the repository at this point in the history
…ponding to the equivalent in find_conflicting. Fuzz tests pass
  • Loading branch information
josephg committed Nov 23, 2023
1 parent b9712c4 commit 8ba1309
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 235 deletions.
239 changes: 124 additions & 115 deletions src/listmerge2/action_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ pub(super) struct EntryState {
impl ConflictSubgraph<EntryState> {
// This method is adapted from the equivalent method in the causal graph code.
fn diff_trace<F: FnMut(usize)>(&self, idx: usize, mut visit: F) {
assert!(self.0[idx].parents.len() >= 2);
assert!(self.entries[idx].parents.len() >= 2);

use DiffFlag::*;
// Sorted highest to lowest.
let mut queue: BinaryHeap<Reverse<(usize, DiffFlag)>> = self.0[idx].parents
let mut queue: BinaryHeap<Reverse<(usize, DiffFlag)>> = self.entries[idx].parents
.iter().enumerate()
.map(|(idx, e)| {
Reverse((*e, if idx == 0 { OnlyA } else { OnlyB }))
Expand Down Expand Up @@ -111,7 +111,7 @@ impl ConflictSubgraph<EntryState> {
// // self.ops[a].state.merge_max_with.push(idx);
// }

let entry = &self.0[idx];
let entry = &self.entries[idx];
if flag == OnlyB && entry.state.visited {
// Oops!
// println!("Need to MAX!");
Expand All @@ -133,22 +133,22 @@ impl ConflictSubgraph<EntryState> {
pub(crate) fn calc_children_needing_index(&mut self) {
// TODO: Merge this with plan_first_pass.
// Iterating with an explicit index to keep the borrowck happy.
for i in 0..self.0.len() {
let entry = &self.0[i];
for i in 0..self.entries.len() {
let entry = &self.entries[i];
if let Some(&first_parent) = entry.parents.first() {
self.0[first_parent].state.children_needing_index += 1;
self.entries[first_parent].state.children_needing_index += 1;
}
}

if !self.0.is_empty() {
self.0[0].state.children_needing_index += 1;
if !self.entries.is_empty() {
self.entries[0].state.children_needing_index += 1;
}
}

fn plan_first_pass(&mut self, b: &Bump) {
use bumpalo::collections::Vec as BumpVec;

if self.0.is_empty() { return; }
if self.entries.is_empty() { return; }
let mut stack = vec![];
let mut current_idx = 0;

Expand All @@ -165,7 +165,7 @@ impl ConflictSubgraph<EntryState> {

loop {
// println!("Visiting idx {current_idx} from {:?}", last_direction);
let mut e = &mut self.0[current_idx];
let mut e = &mut self.entries[current_idx];

let next_direction = 'block: {
// *** Deal with the entry's parents and merging logic ***
Expand Down Expand Up @@ -206,7 +206,7 @@ impl ConflictSubgraph<EntryState> {
maxes.push((current_idx, smallvec![i]));
}
});
e = &mut self.0[current_idx];
e = &mut self.entries[current_idx];
}

// While processing the parents, we increment next when the parent is
Expand Down Expand Up @@ -249,7 +249,7 @@ impl ConflictSubgraph<EntryState> {

assert_eq!(last_direction, Down);

for op in self.0.iter_mut() {
for op in self.entries.iter_mut() {
assert!(op.state.visited);
op.state.visited = false;
op.state.next = 0;
Expand All @@ -258,9 +258,9 @@ impl ConflictSubgraph<EntryState> {
// dbg!(&maxes.len());
for (i, v) in maxes {
for vv in v.iter() {
self.0[*vv].state.children_needing_index += 1;
self.entries[*vv].state.children_needing_index += 1;
}
self.0[i].state.merge_max_with = v;
self.entries[i].state.merge_max_with = v;
}
}

Expand All @@ -274,7 +274,7 @@ impl ConflictSubgraph<EntryState> {
pub(super) fn make_plan(&mut self) -> MergePlan {
let bump = Bump::new();

if self.0.is_empty() {
if self.entries.is_empty() {
return MergePlan { actions: vec![], indexes_used: 0 };
}

Expand All @@ -288,7 +288,7 @@ impl ConflictSubgraph<EntryState> {
let mut index_stack: Vec<Index> = vec![];
// let mut indexes_state: Vec<Option<Frontier>> = vec![Some(Frontier::root())];

let g = &mut self.0;
let g = &mut self.entries;

// Up from some child, or down with an index.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
Expand Down Expand Up @@ -547,7 +547,7 @@ impl ConflictSubgraph<EntryState> {
assert_eq!(concurrency, 0);
assert_eq!(last_direction, Down(Some(0)));

for op in self.0.iter() {
for op in self.entries.iter() {
assert_eq!(op.state.children_needing_index, 0);
}

Expand Down Expand Up @@ -724,7 +724,7 @@ mod test {

#[test]
fn test_trivial_graphs() {
let mut g = ConflictSubgraph(vec![]);
let mut g = ConflictSubgraph { entries: vec![], base_version: Frontier::root() };

g.dbg_check();
let plan = g.make_plan();
Expand All @@ -734,15 +734,18 @@ mod test {
GraphEntrySimple { span: 0.into(), parents: Frontier::root() }
]);

let mut g = ConflictSubgraph(vec![
ConflictGraphEntry {
parents: smallvec![],
span: (0..1).into(),
num_children: 0,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
]);
let mut g = ConflictSubgraph {
entries: vec![
ConflictGraphEntry {
parents: smallvec![],
span: (0..1).into(),
num_children: 0,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
],
base_version: Frontier::root()
};

g.dbg_check();
let plan = g.make_plan();
Expand All @@ -757,36 +760,39 @@ mod test {
GraphEntrySimple { span: 2.into(), parents: Frontier::new_1(0) },
]);

let mut g = ConflictSubgraph(vec![
ConflictGraphEntry {
parents: smallvec![1, 2],
span: (0..0).into(),
num_children: 0,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry {
parents: smallvec![3],
span: 2.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry {
parents: smallvec![3],
span: 1.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry {
parents: smallvec![],
span: 0.into(),
num_children: 2,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
]);
let mut g = ConflictSubgraph {
entries: vec![
ConflictGraphEntry {
parents: smallvec![1, 2],
span: (0..0).into(),
num_children: 0,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry {
parents: smallvec![3],
span: 2.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry {
parents: smallvec![3],
span: 1.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry {
parents: smallvec![],
span: 0.into(),
num_children: 2,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
],
base_version: Frontier::root()
};

g.dbg_check();
let plan = g.make_plan();
Expand All @@ -795,64 +801,67 @@ mod test {

#[test]
fn diamonds() {
let mut g: ConflictSubgraph<EntryState> = ConflictSubgraph(vec![
ConflictGraphEntry { // 0 Y
parents: smallvec![1, 2],
span: Default::default(),
num_children: 0,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 1 ACY
parents: smallvec![6],
span: 4.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 2 D
parents: smallvec![3],
span: 3.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 3 DY
parents: smallvec![4, 5],
span: Default::default(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 4 AD
parents: smallvec![6],
span: 2.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 5 XBD
parents: smallvec![7],
span: 1.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 6 XA -> A
parents: smallvec![7],
span: 0.into(),
num_children: 2,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 7 X
parents: smallvec![],
span: Default::default(),
num_children: 2,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
]);
let mut g: ConflictSubgraph<EntryState> = ConflictSubgraph {
entries: vec![
ConflictGraphEntry { // 0 Y
parents: smallvec![1, 2],
span: Default::default(),
num_children: 0,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 1 ACY
parents: smallvec![6],
span: 4.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 2 D
parents: smallvec![3],
span: 3.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 3 DY
parents: smallvec![4, 5],
span: Default::default(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 4 AD
parents: smallvec![6],
span: 2.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 5 XBD
parents: smallvec![7],
span: 1.into(),
num_children: 1,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 6 XA -> A
parents: smallvec![7],
span: 0.into(),
num_children: 2,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
ConflictGraphEntry { // 7 X
parents: smallvec![],
span: Default::default(),
num_children: 2,
state: Default::default(),
flag: DiffFlag::OnlyB,
},
],
base_version: Frontier::root()
};

g.dbg_check();
let plan = g.make_plan();
Expand Down
Loading

0 comments on commit 8ba1309

Please sign in to comment.