-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Refactory of Fork-Tree data structure #11228
Conversation
Regarding the unsafe parts - I haven't looked at the code very closely, but it might be worthwhile to run the tests through MIRI, and for a core data structure like this one it'd also be nice (if possible) to hook it up to a fuzzying harness and see if it finds anything (if we want to be absolutely sure it's correct). |
Unsafe code has been removed at all. For |
Can you also add a test (or modify an existing one) which tests that the ( |
@koute done |
We should find the deepest ancestor satisfying the predicate regardless of the predicate evaluation result on the found node ancestors. Added one test to excercise the bug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still missing a comment that the iteration order in unspecified. (:
Besides that LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM. Just one thing that might be missing is a custom implementation of Decode
/Encode
since the generated codec will likely use recursion as well. I guess this can be tested by creating a very deep tree and then trying to decode/encode.
Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
@andresilva I will check that and if that is the case I'll open one issue as a reminder to implement it in a separate PR |
* Iterative version of some fork-tree methods * Prune doesn't require its generic args to be 'clone' * Fork-tree import and drain-filter iterative implementations * Fork-tree map iterative implementation * Optimization of some operations, e.g. rebalance only when required * Destructuring assignments not supported yet by stable rustc 1.57 * Safe implementation of 'map' and 'drain_filter' methods * Remove dummy comment * Trigger CI pipeline * Test map for multi-root fork-tree and refactory of `find_node_index_where` * Fix find node index with predicate * Nits * Tree traversal algorithm is not specified * Move unspecified tree traversal warning to 'map' * Immutable 'drain_filter' predicate * Apply suggestions from code review * Remove double mapping Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
* Iterative version of some fork-tree methods * Prune doesn't require its generic args to be 'clone' * Fork-tree import and drain-filter iterative implementations * Fork-tree map iterative implementation * Optimization of some operations, e.g. rebalance only when required * Destructuring assignments not supported yet by stable rustc 1.57 * Safe implementation of 'map' and 'drain_filter' methods * Remove dummy comment * Trigger CI pipeline * Test map for multi-root fork-tree and refactory of `find_node_index_where` * Fix find node index with predicate * Nits * Tree traversal algorithm is not specified * Move unspecified tree traversal warning to 'map' * Immutable 'drain_filter' predicate * Apply suggestions from code review * Remove double mapping Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
* Iterative version of some fork-tree methods * Prune doesn't require its generic args to be 'clone' * Fork-tree import and drain-filter iterative implementations * Fork-tree map iterative implementation * Optimization of some operations, e.g. rebalance only when required * Destructuring assignments not supported yet by stable rustc 1.57 * Safe implementation of 'map' and 'drain_filter' methods * Remove dummy comment * Trigger CI pipeline * Test map for multi-root fork-tree and refactory of `find_node_index_where` * Fix find node index with predicate * Nits * Tree traversal algorithm is not specified * Move unspecified tree traversal warning to 'map' * Immutable 'drain_filter' predicate * Apply suggestions from code review * Remove double mapping Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
WARNING
This is a critical structure used by both GRANDPA and BABE consensus algorithms.
As such, a rigorous review is required
A good part of the methods where rewritten in order to:
rebalance
only when strictly required (traversal is not free)A couple of well circumscribedunsafe
operations were introduced.In particular, to traverse the tree with the intent to mutate some parts of it, in an iterative implementation we need to maintain multiple mutable references to some nodes (in a stack).This is not allowed in safe Rust.Here we're resorting to raw pointers in a couple of places with extra attention to only use them for data that has a provable stable address (not subject to relocation/deletion)