Skip to content

Commit

Permalink
Optimize multi-level parents builder (kaspanet#79)
Browse files Browse the repository at this point in the history
* Flip loops order

* Move empty level check to inner

* Use BlockHashMap/Set

* Filter inner duplicates with an hash set

* Apply clippy suggestion

* Avoid outer vector

* Use retain

* Make query of origin children future more readable

* We need to iterate parent's parents only if parent is not at block_level

* Fix comments

* Use smallvec for ref blocks

* Mark first parent's parents

* Use u8 for block_level loop variable

* And comment and turn some reachability queries into a lazy evaluation

* Add a test for the case of multiple parallel high-level parents which are below the pruning point
  • Loading branch information
michaelsutton authored Nov 28, 2022
1 parent 411bd16 commit 180bd07
Show file tree
Hide file tree
Showing 3 changed files with 251 additions and 124 deletions.
11 changes: 11 additions & 0 deletions consensus/src/model/services/reachability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub trait ReachabilityService {
fn is_dag_ancestor_of(&self, this: Hash, queried: Hash) -> bool;
fn is_dag_ancestor_of_any(&self, this: Hash, queried: &mut impl Iterator<Item = Hash>) -> bool;
fn is_any_dag_ancestor(&self, list: &mut impl Iterator<Item = Hash>, queried: Hash) -> bool;
fn is_any_dag_ancestor_result(&self, list: &mut impl Iterator<Item = Hash>, queried: Hash) -> Result<bool>;
fn get_next_chain_ancestor(&self, descendant: Hash, ancestor: Hash) -> Hash;
}

Expand Down Expand Up @@ -50,6 +51,16 @@ impl<T: ReachabilityStoreReader + ?Sized> ReachabilityService for MTReachability
list.any(|hash| inquirer::is_dag_ancestor_of(read_guard.deref(), hash, queried).unwrap())
}

fn is_any_dag_ancestor_result(&self, list: &mut impl Iterator<Item = Hash>, queried: Hash) -> Result<bool> {
let read_guard = self.store.read();
for hash in list {
if inquirer::is_dag_ancestor_of(read_guard.deref(), hash, queried)? {
return Ok(true);
}
}
Ok(false)
}

fn is_dag_ancestor_of_any(&self, this: Hash, queried: &mut impl Iterator<Item = Hash>) -> bool {
let read_guard = self.store.read();
queried.any(|hash| inquirer::is_dag_ancestor_of(read_guard.deref(), this, hash).unwrap())
Expand Down
Loading

0 comments on commit 180bd07

Please sign in to comment.