This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fork-tree: add support for find_node_mut_where #4784
Merged
Merged
Changes from 1 commit
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
6d9f3a9
fork-tree: add support for find_node_mut_where
sorpaas 590e74c
Update utils/fork-tree/src/lib.rs
sorpaas 629f72b
Update utils/fork-tree/src/lib.rs
sorpaas 1db8331
Update utils/fork-tree/src/lib.rs
sorpaas 396cd9b
Fix calling name
sorpaas 1fa236e
Update utils/fork-tree/src/lib.rs
sorpaas 905bdcd
doc: be precise what is "least significant" index
sorpaas fae4c94
Merge branch 'master' of https://github.com/paritytech/substrate into…
sorpaas File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -200,7 +200,7 @@ impl<H, N, V> ForkTree<H, N, V> where | |||||
| data, | ||||||
| hash: hash, | ||||||
| number: number, | ||||||
| children: Vec::new(), | ||||||
| children: Vec::new(), | ||||||
| }); | ||||||
|
|
||||||
| self.rebalance(); | ||||||
|
|
@@ -232,10 +232,10 @@ impl<H, N, V> ForkTree<H, N, V> where | |||||
| number: &N, | ||||||
| is_descendent_of: &F, | ||||||
| predicate: &P, | ||||||
| ) -> Result<Option<&Node<H, N, V>>, Error<E>> | ||||||
| where E: std::error::Error, | ||||||
| F: Fn(&H, &H) -> Result<bool, E>, | ||||||
| P: Fn(&V) -> bool, | ||||||
| ) -> Result<Option<&Node<H, N, V>>, Error<E>> where | ||||||
| E: std::error::Error, | ||||||
| F: Fn(&H, &H) -> Result<bool, E>, | ||||||
| P: Fn(&V) -> bool, | ||||||
| { | ||||||
| // search for node starting from all roots | ||||||
| for root in self.roots.iter() { | ||||||
|
|
@@ -250,6 +250,31 @@ impl<H, N, V> ForkTree<H, N, V> where | |||||
| Ok(None) | ||||||
| } | ||||||
|
|
||||||
| /// Same as `find_node_where`, but returns mutable reference. | ||||||
| pub fn find_node_mut_where<F, E, P>( | ||||||
|
sorpaas marked this conversation as resolved.
Outdated
|
||||||
| &mut self, | ||||||
| hash: &H, | ||||||
| number: &N, | ||||||
| is_descendent_of: &F, | ||||||
| predicate: &P, | ||||||
| ) -> Result<Option<&mut Node<H, N, V>>, Error<E>> where | ||||||
| E: std::error::Error, | ||||||
| F: Fn(&H, &H) -> Result<bool, E>, | ||||||
| P: Fn(&V) -> bool, | ||||||
| { | ||||||
| // search for node starting from all roots | ||||||
| for root in self.roots.iter_mut() { | ||||||
| let node = root.find_node_mut_where(hash, number, is_descendent_of, predicate)?; | ||||||
|
|
||||||
| // found the node, early exit | ||||||
| if let FindOutcome::Found(node) = node { | ||||||
| return Ok(Some(node)); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| Ok(None) | ||||||
| } | ||||||
|
|
||||||
| /// Finalize a root in the tree and return it, return `None` in case no root | ||||||
| /// with the given hash exists. All other roots are pruned, and the children | ||||||
| /// of the finalized node become the new roots. | ||||||
|
|
@@ -609,16 +634,17 @@ mod node_implementation { | |||||
| /// when the predicate fails. | ||||||
| /// The given function `is_descendent_of` should return `true` if the second hash (target) | ||||||
| /// is a descendent of the first hash (base). | ||||||
| // FIXME: it would be useful if this returned a mutable reference but | ||||||
| // rustc can't deal with lifetimes properly. an option would be to try | ||||||
| // an iterative definition instead. | ||||||
| pub fn find_node_where<F, P, E>( | ||||||
| /// | ||||||
| /// The returned indexes are from last to first, meaning the last is the least significant | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's not clear what "least significant" means in this comment, but from reading the code i take it to be the earlier index in the traversal path.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I updated the docs just calling it the "earliest" and "final" index. |
||||||
| /// child, and the first is the most significant child. An empty list means that the | ||||||
| /// current node is the result. | ||||||
| pub fn find_node_index_where<F, P, E>( | ||||||
| &self, | ||||||
| hash: &H, | ||||||
| number: &N, | ||||||
| is_descendent_of: &F, | ||||||
| predicate: &P, | ||||||
| ) -> Result<FindOutcome<&Node<H, N, V>>, Error<E>> | ||||||
| ) -> Result<FindOutcome<Vec<usize>>, Error<E>> | ||||||
| where E: std::error::Error, | ||||||
| F: Fn(&H, &H) -> Result<bool, E>, | ||||||
| P: Fn(&V) -> bool, | ||||||
|
|
@@ -631,11 +657,14 @@ mod node_implementation { | |||||
| let mut known_descendent_of = false; | ||||||
|
|
||||||
| // continue depth-first search through all children | ||||||
| for node in self.children.iter() { | ||||||
| for (i, node) in self.children.iter().enumerate() { | ||||||
| // found node, early exit | ||||||
| match node.find_node_where(hash, number, is_descendent_of, predicate)? { | ||||||
| match node.find_node_index_where(hash, number, is_descendent_of, predicate)? { | ||||||
| FindOutcome::Abort => return Ok(FindOutcome::Abort), | ||||||
| FindOutcome::Found(x) => return Ok(FindOutcome::Found(x)), | ||||||
| FindOutcome::Found(mut x) => { | ||||||
| x.push(i); | ||||||
| return Ok(FindOutcome::Found(x)) | ||||||
| }, | ||||||
| FindOutcome::Failure(true) => { | ||||||
| // if the block was a descendent of this child, | ||||||
| // then it cannot be a descendent of any others, | ||||||
|
|
@@ -655,14 +684,78 @@ mod node_implementation { | |||||
| if is_descendent_of { | ||||||
| // if the predicate passes we return the node | ||||||
| if predicate(&self.data) { | ||||||
| return Ok(FindOutcome::Found(self)); | ||||||
| return Ok(FindOutcome::Found(Vec::new())); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| // otherwise, tell our ancestor that we failed, and whether | ||||||
| // the block was a descendent. | ||||||
| Ok(FindOutcome::Failure(is_descendent_of)) | ||||||
| } | ||||||
|
|
||||||
| /// Find a node in the tree that is the deepest ancestor of the given | ||||||
| /// block hash which also passes the given predicate, backtracking | ||||||
| /// when the predicate fails. | ||||||
| /// The given function `is_descendent_of` should return `true` if the second hash (target) | ||||||
| /// is a descendent of the first hash (base). | ||||||
| pub fn find_node_where<F, P, E>( | ||||||
| &self, | ||||||
| hash: &H, | ||||||
| number: &N, | ||||||
| is_descendent_of: &F, | ||||||
| predicate: &P, | ||||||
| ) -> Result<FindOutcome<&Node<H, N, V>>, Error<E>> | ||||||
| where E: std::error::Error, | ||||||
| F: Fn(&H, &H) -> Result<bool, E>, | ||||||
| P: Fn(&V) -> bool, | ||||||
| { | ||||||
| let outcome = self.find_node_index_where(hash, number, is_descendent_of, predicate)?; | ||||||
|
|
||||||
| match outcome { | ||||||
| FindOutcome::Abort => Ok(FindOutcome::Abort), | ||||||
| FindOutcome::Failure(f) => Ok(FindOutcome::Failure(f)), | ||||||
| FindOutcome::Found(mut indexes) => { | ||||||
| let mut cur = self; | ||||||
|
|
||||||
| while let Some(i) = indexes.pop() { | ||||||
| cur = &cur.children[i]; | ||||||
| } | ||||||
| Ok(FindOutcome::Found(cur)) | ||||||
| }, | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| /// Find a node in the tree that is the deepest ancestor of the given | ||||||
| /// block hash which also passes the given predicate, backtracking | ||||||
| /// when the predicate fails. | ||||||
| /// The given function `is_descendent_of` should return `true` if the second hash (target) | ||||||
| /// is a descendent of the first hash (base). | ||||||
| pub fn find_node_mut_where<F, P, E>( | ||||||
|
sorpaas marked this conversation as resolved.
Outdated
|
||||||
| &mut self, | ||||||
| hash: &H, | ||||||
| number: &N, | ||||||
| is_descendent_of: &F, | ||||||
| predicate: &P, | ||||||
| ) -> Result<FindOutcome<&mut Node<H, N, V>>, Error<E>> | ||||||
| where E: std::error::Error, | ||||||
| F: Fn(&H, &H) -> Result<bool, E>, | ||||||
| P: Fn(&V) -> bool, | ||||||
| { | ||||||
| let outcome = self.find_node_index_where(hash, number, is_descendent_of, predicate)?; | ||||||
|
|
||||||
| match outcome { | ||||||
| FindOutcome::Abort => Ok(FindOutcome::Abort), | ||||||
| FindOutcome::Failure(f) => Ok(FindOutcome::Failure(f)), | ||||||
| FindOutcome::Found(mut indexes) => { | ||||||
| let mut cur = self; | ||||||
|
|
||||||
| while let Some(i) = indexes.pop() { | ||||||
| cur = &mut cur.children[i]; | ||||||
| } | ||||||
| Ok(FindOutcome::Found(cur)) | ||||||
| }, | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
|
|
||||||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.