removed recursion in load_causal_past

master
Niko PLP 4 months ago
parent 5155dc208b
commit a983205baa
  1. 89
      ng-repo/src/branch.rs
  2. 37
      ng-repo/src/repo.rs
  3. 18
      ng-verifier/src/verifier.rs

@ -180,15 +180,17 @@ impl Branch {
/// optionally collecting the missing objects/blocks that couldn't be found locally on the way,
/// and also optionally, collecting the commits of `theirs` found on the way
pub fn load_causal_past(
cobj: &Object,
recursor: &mut Vec<(ObjectId, Option<ObjectId>)>,
store: &Store,
theirs: &HashSet<ObjectId>,
visited: &mut HashMap<ObjectId, DagNode>,
missing: &mut Option<&mut HashSet<ObjectId>>,
future: Option<ObjectId>,
theirs_found: &mut Option<&mut HashSet<ObjectId>>,
theirs_filter: &Option<Filter>,
) -> Result<(), ObjectParseError> {
while let Some((id, future)) = recursor.pop() {
match Object::load(id, None, store) {
Ok(cobj) => {
let id = cobj.id();
// check if this commit object is present in theirs or has already been visited in the current walk
@ -215,29 +217,42 @@ impl Branch {
let pasts = cobj.acks_and_nacks();
new_node_to_insert.past.extend(pasts.iter().cloned());
visited.insert(id, new_node_to_insert);
for past_id in pasts {
match Object::load(past_id, None, store) {
Ok(o) => {
Self::load_causal_past(
&o,
store,
theirs,
visited,
missing,
Some(id),
theirs_found,
theirs_filter,
)?;
recursor.extend(pasts.into_iter().map(|past_id| (past_id, Some(id))));
// for past_id in pasts {
// match Object::load(past_id, None, store) {
// Ok(o) => {
// Self::load_causal_past(
// recursor,
// store,
// theirs,
// visited,
// missing,
// theirs_found,
// theirs_filter,
// )?;
// }
// Err(ObjectParseError::MissingBlocks(blocks)) => {
// missing.as_mut().map(|m| m.extend(blocks));
// }
// Err(e) => return Err(e),
// }
// }
}
} else if theirs_found.is_some() {
theirs_found.as_mut().unwrap().insert(id);
}
}
Err(ObjectParseError::MissingBlocks(blocks)) => {
if future.is_some() {
missing.as_mut().map(|m| m.extend(blocks));
}
Err(e) => return Err(e),
}
Err(e) => {
if future.is_some() {
return Err(e);
}
}
}
} else if theirs_found.is_some() {
theirs_found.as_mut().unwrap().insert(id);
}
Ok(())
}
@ -260,22 +275,20 @@ impl Branch {
// their commits
let mut theirs: HashMap<ObjectId, DagNode> = HashMap::new();
//
let mut recursor: Vec<(ObjectId, Option<ObjectId>)> =
known_heads.iter().map(|h| (h.clone(), None)).collect();
// collect causal past of known_heads
for id in known_heads {
if let Ok(cobj) = Object::load(*id, None, store) {
// we silently discard any load error on the known_heads as the responder might not know them (yet).
Self::load_causal_past(
&cobj,
&mut recursor,
store,
&HashSet::new(),
&mut theirs,
&mut None,
None,
&mut None,
&None,
)?;
}
// we silently discard any load error on the known_heads as the responder might not know them (yet).
}
// log_debug!("their causal past \n{}", Dag(&theirs));
@ -291,23 +304,35 @@ impl Branch {
None
};
let mut recursor: Vec<(ObjectId, Option<ObjectId>)> =
target_heads.map(|h| (h.clone(), None)).collect();
// collect all commits reachable from target_heads
// up to the root or until encountering a commit from theirs
for id in target_heads {
if let Ok(cobj) = Object::load(id, None, store) {
// we silently discard any load error on the target_heads as they can be wrong if the requester is confused about what the responder has locally.
Self::load_causal_past(
&cobj,
&mut recursor,
store,
&theirs,
&mut visited,
&mut None,
None,
&mut None,
&filter,
)?;
}
// we silently discard any load error on the target_heads as they can be wrong if the requester is confused about what the responder has locally.
}
// for id in target_heads {
// if let Ok(cobj) = Object::load(id, None, store) {
// Self::load_causal_past(
// &cobj,
// store,
// &theirs,
// &mut visited,
// &mut None,
// None,
// &mut None,
// &filter,
// )?;
// }
// }
// log_debug!("what we have here \n{}", Dag(&visited));

@ -191,11 +191,12 @@ impl Repo {
fn load_causal_past(
&self,
cobj: &Commit,
recursor: &mut Vec<(BlockRef, Option<ObjectId>)>,
visited: &mut HashMap<ObjectId, (HashSet<ObjectId>, CommitInfo)>,
future: Option<ObjectId>,
) -> Result<Option<ObjectId>, VerifierError> {
let mut root = None;
while let Some((next_ref, future)) = recursor.pop() {
if let Ok(cobj) = Commit::load(next_ref, &self.store, true) {
let id = cobj.id().unwrap();
if let Some((future_set, _)) = visited.get_mut(&id) {
// we update the future
@ -269,13 +270,16 @@ impl Repo {
y: 0,
};
visited.insert(id, (future.map_or([].into(), |f| [f].into()), commit_info));
if real_acks.is_empty() {
if real_acks.is_empty() && root.is_none() {
root = Some(next_future);
}
for past_ref in real_acks {
let o = Commit::load(past_ref, &self.store, true)?;
if let Some(r) = self.load_causal_past(&o, visited, Some(next_future))? {
root = Some(r);
recursor.extend(real_acks.into_iter().map(|br| (br, Some(next_future))));
// for past_ref in real_acks {
// let o = Commit::load(past_ref, &self.store, true)?;
// if let Some(r) = self.load_causal_past(&o, visited, Some(next_future))? {
// root = Some(r);
// }
// }
}
}
}
@ -458,15 +462,22 @@ impl Repo {
// }
let mut visited = HashMap::new();
let mut root = None;
for id in heads {
if let Ok(cobj) = Commit::load(id.clone(), &self.store, true) {
let r = self.load_causal_past(&cobj, &mut visited, None)?;
//log_debug!("ROOT? {:?}", r.map(|rr| rr.to_string()));
let mut recursor: Vec<(BlockRef, Option<ObjectId>)> =
heads.iter().map(|h| (h.clone(), None)).collect();
let r = self.load_causal_past(&mut recursor, &mut visited)?;
if r.is_some() {
root = r;
}
}
}
// for id in heads {
// if let Ok(cobj) = Commit::load(id.clone(), &self.store, true) {
// let r = self.load_causal_past(&cobj, &mut visited, None)?;
// //log_debug!("ROOT? {:?}", r.map(|rr| rr.to_string()));
// if r.is_some() {
// root = r;
// }
// }
// }
// for h in visited.keys() {
// log_debug!("VISITED {}", h);
// }

@ -1609,21 +1609,25 @@ impl Verifier {
let mut theirs_found = HashSet::new();
let mut visited = HashMap::new();
for our in ours_set.iter() {
//log_info!("OUR HEADS {}", our);
if let Ok(cobj) = Object::load(*our, None, &repo.store) {
let mut recursor: Vec<(ObjectId, Option<ObjectId>)> =
ours_set.iter().map(|h| (h.clone(), None)).collect();
let _ = Branch::load_causal_past(
&cobj,
&mut recursor,
&repo.store,
&theirs,
&mut visited,
&mut None,
None,
&mut Some(&mut theirs_found),
&None,
);
}
}
// for our in ours_set.iter() {
// //log_info!("OUR HEADS {}", our);
// if let Ok(cobj) = Object::load(*our, None, &repo.store) {
// let _ =
// }
// }
let theirs_not_found: Vec<ObjectId> =
theirs.difference(&theirs_found).cloned().collect();

Loading…
Cancel
Save