pub struct ForkTree<H, N, V> { /* private fields */ }
Expand description
A tree data structure that stores several nodes across multiple branches. Top-level branches are called roots. The tree has functionality for finalizing nodes, which means that that node is traversed, and all competing branches are pruned. It also guarantees that nodes in the tree are finalized in order. Each node is uniquely identified by its hash but can be ordered by its number. In order to build the tree an external function must be provided when interacting with the tree to establish a node’s ancestry.
Implementations
sourceimpl<H, N, V> ForkTree<H, N, V> where
H: PartialEq + Clone,
N: Ord + Clone,
V: Clone,
impl<H, N, V> ForkTree<H, N, V> where
H: PartialEq + Clone,
N: Ord + Clone,
V: Clone,
sourcepub fn prune<F, E, P>(
&mut self,
hash: &H,
number: &N,
is_descendent_of: &F,
predicate: &P
) -> Result<impl Iterator<Item = (H, N, V)>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
pub fn prune<F, E, P>(
&mut self,
hash: &H,
number: &N,
is_descendent_of: &F,
predicate: &P
) -> Result<impl Iterator<Item = (H, N, V)>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
Prune the tree, removing all non-canonical nodes. We find the node in the
tree that is the deepest ancestor of the given hash and that passes the
given predicate. If such a node exists, we re-root the tree to this
node. Otherwise the tree remains unchanged. The given function
is_descendent_of
should return true
if the second hash (target) is a
descendent of the first hash (base).
Returns all pruned node data.
sourceimpl<H, N, V> ForkTree<H, N, V> where
H: PartialEq,
N: Ord,
impl<H, N, V> ForkTree<H, N, V> where
H: PartialEq,
N: Ord,
sourcepub fn rebalance(&mut self)
pub fn rebalance(&mut self)
Rebalance the tree, i.e. sort child nodes by max branch depth (decreasing).
Most operations in the tree are performed with depth-first search starting from the leftmost node at every level, since this tree is meant to be used in a blockchain context, a good heuristic is that the node we’ll be looking for at any point will likely be in one of the deepest chains (i.e. the longest ones).
sourcepub fn import<F, E>(
&mut self,
hash: H,
number: N,
data: V,
is_descendent_of: &F
) -> Result<bool, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
pub fn import<F, E>(
&mut self,
hash: H,
number: N,
data: V,
is_descendent_of: &F
) -> Result<bool, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
Import a new node into the tree. The given function is_descendent_of
should return true
if the second hash (target) is a descendent of the
first hash (base). This method assumes that nodes in the same branch are
imported in order.
Returns true
if the imported node is a root.
sourcepub fn roots(&self) -> impl Iterator<Item = (&H, &N, &V)>
pub fn roots(&self) -> impl Iterator<Item = (&H, &N, &V)>
Iterates over the existing roots in the tree.
sourcepub fn iter(&self) -> impl Iterator<Item = (&H, &N, &V)>
pub fn iter(&self) -> impl Iterator<Item = (&H, &N, &V)>
Iterates the nodes in the tree in pre-order.
sourcepub fn find_node_where<F, E, P>(
&self,
hash: &H,
number: &N,
is_descendent_of: &F,
predicate: &P
) -> Result<Option<&Node<H, N, V>>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
pub fn find_node_where<F, E, P>(
&self,
hash: &H,
number: &N,
is_descendent_of: &F,
predicate: &P
) -> Result<Option<&Node<H, N, V>>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
Find a node in the tree that is the deepest ancestor of the given
block hash and which passes the given predicate. The given function
is_descendent_of
should return true
if the second hash (target)
is a descendent of the first hash (base).
sourcepub fn map<VT, F>(self, f: &mut F) -> ForkTree<H, N, VT> where
F: FnMut(&H, &N, V) -> VT,
pub fn map<VT, F>(self, f: &mut F) -> ForkTree<H, N, VT> where
F: FnMut(&H, &N, V) -> VT,
Map fork tree into values of new types.
sourcepub fn find_node_where_mut<F, E, P>(
&mut self,
hash: &H,
number: &N,
is_descendent_of: &F,
predicate: &P
) -> Result<Option<&mut Node<H, N, V>>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
pub fn find_node_where_mut<F, E, P>(
&mut self,
hash: &H,
number: &N,
is_descendent_of: &F,
predicate: &P
) -> Result<Option<&mut Node<H, N, V>>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
Same as find_node_where
, but returns mutable reference.
sourcepub fn find_node_index_where<F, E, P>(
&self,
hash: &H,
number: &N,
is_descendent_of: &F,
predicate: &P
) -> Result<Option<Vec<usize>>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
pub fn find_node_index_where<F, E, P>(
&self,
hash: &H,
number: &N,
is_descendent_of: &F,
predicate: &P
) -> Result<Option<Vec<usize>>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
Same as find_node_where
, but returns indexes.
sourcepub fn finalize_root(&mut self, hash: &H) -> Option<V>
pub fn finalize_root(&mut self, hash: &H) -> Option<V>
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.
sourcepub fn finalize<F, E>(
&mut self,
hash: &H,
number: N,
is_descendent_of: &F
) -> Result<FinalizationResult<V>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
pub fn finalize<F, E>(
&mut self,
hash: &H,
number: N,
is_descendent_of: &F
) -> Result<FinalizationResult<V>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
Finalize a node in the tree. This method will make sure that the node
being finalized is either an existing root (and return its data), or a
node from a competing branch (not in the tree), tree pruning is done
accordingly. The given function is_descendent_of
should return true
if the second hash (target) is a descendent of the first hash (base).
sourcepub fn finalize_with_ancestors<F, E>(
&mut self,
hash: &H,
number: N,
is_descendent_of: &F
) -> Result<FinalizationResult<V>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
pub fn finalize_with_ancestors<F, E>(
&mut self,
hash: &H,
number: N,
is_descendent_of: &F
) -> Result<FinalizationResult<V>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
Finalize a node in the tree and all its ancestors. The given function
is_descendent_of
should return true
if the second hash (target) is
sourcepub fn finalizes_any_with_descendent_if<F, P, E>(
&self,
hash: &H,
number: N,
is_descendent_of: &F,
predicate: P
) -> Result<Option<bool>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
pub fn finalizes_any_with_descendent_if<F, P, E>(
&self,
hash: &H,
number: N,
is_descendent_of: &F,
predicate: P
) -> Result<Option<bool>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
Checks if any node in the tree is finalized by either finalizing the
node itself or a child node that’s not in the tree, guaranteeing that
the node being finalized isn’t a descendent of any of the node’s
children. Returns Some(true)
if the node being finalized is a root,
Some(false)
if the node being finalized is not a root, and None
if
no node in the tree is finalized. The given predicate
is checked on
the prospective finalized root and must pass for finalization to occur.
The given function is_descendent_of
should return true
if the second
hash (target) is a descendent of the first hash (base).
sourcepub fn finalize_with_descendent_if<F, P, E>(
&mut self,
hash: &H,
number: N,
is_descendent_of: &F,
predicate: P
) -> Result<FinalizationResult<V>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
pub fn finalize_with_descendent_if<F, P, E>(
&mut self,
hash: &H,
number: N,
is_descendent_of: &F,
predicate: P
) -> Result<FinalizationResult<V>, Error<E>> where
E: Error,
F: Fn(&H, &H) -> Result<bool, E>,
P: Fn(&V) -> bool,
Finalize a root in the tree by either finalizing the node itself or a
child node that’s not in the tree, guaranteeing that the node being
finalized isn’t a descendent of any of the root’s children. The given
predicate
is checked on the prospective finalized root and must pass for
finalization to occur. The given function is_descendent_of
should
return true
if the second hash (target) is a descendent of the first
hash (base).
Trait Implementations
sourceimpl<H, N, V> Decode for ForkTree<H, N, V> where
Vec<Node<H, N, V>>: Decode,
Vec<Node<H, N, V>>: Decode,
Option<N>: Decode,
Option<N>: Decode,
impl<H, N, V> Decode for ForkTree<H, N, V> where
Vec<Node<H, N, V>>: Decode,
Vec<Node<H, N, V>>: Decode,
Option<N>: Decode,
Option<N>: Decode,
sourcefn decode<__CodecInputEdqy: Input>(
__codec_input_edqy: &mut __CodecInputEdqy
) -> Result<Self, Error>
fn decode<__CodecInputEdqy: Input>(
__codec_input_edqy: &mut __CodecInputEdqy
) -> Result<Self, Error>
Attempt to deserialise the value from input.
sourcefn skip<I>(input: &mut I) -> Result<(), Error> where
I: Input,
fn skip<I>(input: &mut I) -> Result<(), Error> where
I: Input,
Attempt to skip the encoded value from input. Read more
sourcefn encoded_fixed_size() -> Option<usize>
fn encoded_fixed_size() -> Option<usize>
Returns the fixed encoded size of the type. Read more
sourceimpl<H, N, V> Encode for ForkTree<H, N, V> where
Vec<Node<H, N, V>>: Encode,
Vec<Node<H, N, V>>: Encode,
Option<N>: Encode,
Option<N>: Encode,
impl<H, N, V> Encode for ForkTree<H, N, V> where
Vec<Node<H, N, V>>: Encode,
Vec<Node<H, N, V>>: Encode,
Option<N>: Encode,
Option<N>: Encode,
sourcefn encode_to<__CodecOutputEdqy: Output + ?Sized>(
&self,
__codec_dest_edqy: &mut __CodecOutputEdqy
)
fn encode_to<__CodecOutputEdqy: Output + ?Sized>(
&self,
__codec_dest_edqy: &mut __CodecOutputEdqy
)
Convert self to a slice and append it to the destination.
sourcefn size_hint(&self) -> usize
fn size_hint(&self) -> usize
If possible give a hint of expected size of the encoding. Read more
sourcefn using_encoded<R, F>(&self, f: F) -> R where
F: FnOnce(&[u8]) -> R,
fn using_encoded<R, F>(&self, f: F) -> R where
F: FnOnce(&[u8]) -> R,
Convert self to a slice and then invoke the given closure with it.
sourcefn encoded_size(&self) -> usize
fn encoded_size(&self) -> usize
Calculates the encoded size. Read more
sourceimpl<H: PartialEq, N: PartialEq, V: PartialEq> PartialEq<ForkTree<H, N, V>> for ForkTree<H, N, V>
impl<H: PartialEq, N: PartialEq, V: PartialEq> PartialEq<ForkTree<H, N, V>> for ForkTree<H, N, V>
impl<H, N, V> EncodeLike<ForkTree<H, N, V>> for ForkTree<H, N, V> where
Vec<Node<H, N, V>>: Encode,
Vec<Node<H, N, V>>: Encode,
Option<N>: Encode,
Option<N>: Encode,
impl<H, N, V> StructuralPartialEq for ForkTree<H, N, V>
Auto Trait Implementations
impl<H, N, V> RefUnwindSafe for ForkTree<H, N, V> where
H: RefUnwindSafe,
N: RefUnwindSafe,
V: RefUnwindSafe,
impl<H, N, V> Send for ForkTree<H, N, V> where
H: Send,
N: Send,
V: Send,
impl<H, N, V> Sync for ForkTree<H, N, V> where
H: Sync,
N: Sync,
V: Sync,
impl<H, N, V> Unpin for ForkTree<H, N, V> where
H: Unpin,
N: Unpin,
V: Unpin,
impl<H, N, V> UnwindSafe for ForkTree<H, N, V> where
H: UnwindSafe,
N: UnwindSafe,
V: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> DecodeLimit for T where
T: Decode,
impl<T> DecodeLimit for T where
T: Decode,
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcepub fn to_owned(&self) -> T
pub fn to_owned(&self) -> T
Creates owned data from borrowed data, usually by cloning. Read more
sourcepub fn clone_into(&self, target: &mut T)
pub fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more