fn split_extension<K, V>(
    new_leaf_path: &[u8],
    existing_extension: Trie<K, V>,
    mut parents: Parents<K, V>,
) -> Result<SplitResult<K, V>, bytesrepr::Error>
where
    K: ToBytes + Clone,
    V: ToBytes + Clone,
{
    // TODO: add is_extension() method to Trie
    let (affix, pointer) = match existing_extension {
        Trie::Extension { affix, pointer } => (affix, pointer),
        _ => panic!("existing_extension must be an extension"),
    };
    let parents_path = get_parents_path(&parents);
    // Get the path to the existing extension node
    let existing_extension_path: Vec<u8> =
        parents_path.iter().chain(affix.iter()).cloned().collect();
    // Get the path that the new leaf and existing leaf share
    let shared_path = common_prefix(new_leaf_path, &existing_extension_path);
    // Create an affix for a possible parent extension above the new
    // node.
    let parent_extension_affix = shared_path[parents_path.len()..].to_vec();
    // Create an affix for a possible child extension between the new
    // node and the node that the existing extension pointed to.
    let child_extension_affix = affix[parent_extension_affix.len() + 1..].to_vec();
    // Create a child extension (paired with its hash) if necessary
    let maybe_hashed_child_extension: Option<(Digest, Trie<K, V>)> =
        if child_extension_affix.is_empty() {
            None
        } else {
            let child_extension = Trie::extension(child_extension_affix.to_vec(), pointer);
            let child_extension_bytes = child_extension.to_bytes()?;
            let child_extension_hash = Digest::hash(&child_extension_bytes);
            Some((child_extension_hash, child_extension))
        };
    // Assemble a new node.
    let new_node: Trie<K, V> = {
        let index = existing_extension_path[shared_path.len()];
        let pointer = maybe_hashed_child_extension
            .to_owned()
            .map_or(pointer, |(hash, _)| Pointer::NodePointer(hash));
        Trie::node(&[(index, pointer)])
    };
    // Create a parent extension if necessary
    if !parent_extension_affix.is_empty() {
        let new_node_bytes = new_node.to_bytes()?;
        let new_node_hash = Digest::hash(&new_node_bytes);
        let parent_extension = Trie::extension(
            parent_extension_affix.to_vec(),
            Pointer::NodePointer(new_node_hash),
        );
        parents.push((parent_extension_affix[0], parent_extension));
    }
    Ok(SplitResult {
        new_node,
        parents,
        maybe_hashed_child_extension,
    })
}
/// Takes a path to a new leaf, an existing extension that leaf collides with,
/// and the parents of that extension.  Creates a new node and possible parent
/// and child extensions.  The node pointer contained in the existing extension
/// is repositioned in the new node or the possible child extension.  The
/// possible parent extension is added to parents.  Returns the new node,
/// parents, and the the possible child extension (paired with its hash).
/// The new node and parents can be used by [`add_node_to_parents`], and the
/// new hashed child extension can be added to the list of new trie elements.
Takes a path to a new leaf, an existing extension that leaf collides with,
and the parents of that extension.  Creates a new node and possible parent
and child extensions.  The node pointer contained in the existing extension
is repositioned in the new node or the possible child extension.  The
possible parent extension is added to parents.  Returns the new node,
parents, and the the possible child extension (paired with its hash).
The new node and parents can be used by [`add_node_to_parents`], and the
new hashed child extension can be added to the list of new trie elements.
Takes a path to a new leaf an existing extension that leaf collides with and the parents of that extension . Creates a new node and possible parent and child extensions . The node pointer contained in the existing extension is repositioned in the new node or the possible child extension . The possible parent extension is added to parents . Returns the new node parents and the the possible child extension ( paired with its hash ) . The new node and parents can be used by [ ` add_node_to_parents ` ] and the new hashed child extension can be added to the list of new trie elements .
fn split_extension<K, V>(
    new_leaf_path: &[u8],
    existing_extension: Trie<K, V>,
    mut parents: Parents<K, V>,
) -> Result<SplitResult<K, V>, bytesrepr::Error>
where
    K: ToBytes + Clone,
    V: ToBytes + Clone,
{
    // TODO: add is_extension() method to Trie
    let (affix, pointer) = match existing_extension {
        Trie::Extension { affix, pointer } => (affix, pointer),
        _ => panic!("existing_extension must be an extension"),
    };
    let parents_path = get_parents_path(&parents);
    // Get the path to the existing extension node
    let existing_extension_path: Vec<u8> =
        parents_path.iter().chain(affix.iter()).cloned().collect();
    // Get the path that the new leaf and existing leaf share
    let shared_path = common_prefix(new_leaf_path, &existing_extension_path);
    // Create an affix for a possible parent extension above the new
    // node.
    let parent_extension_affix = shared_path[parents_path.len()..].to_vec();
    // Create an affix for a possible child extension between the new
    // node and the node that the existing extension pointed to.
    let child_extension_affix = affix[parent_extension_affix.len() + 1..].to_vec();
    // Create a child extension (paired with its hash) if necessary
    let maybe_hashed_child_extension: Option<(Digest, Trie<K, V>)> =
        if child_extension_affix.is_empty() {
            None
        } else {
            let child_extension = Trie::extension(child_extension_affix.to_vec(), pointer);
            let child_extension_bytes = child_extension.to_bytes()?;
            let child_extension_hash = Digest::hash(&child_extension_bytes);
            Some((child_extension_hash, child_extension))
        };
    // Assemble a new node.
    let new_node: Trie<K, V> = {
        let index = existing_extension_path[shared_path.len()];
        let pointer = maybe_hashed_child_extension
            .to_owned()
            .map_or(pointer, |(hash, _)| Pointer::NodePointer(hash));
        Trie::node(&[(index, pointer)])
    };
    // Create a parent extension if necessary
    if !parent_extension_affix.is_empty() {
        let new_node_bytes = new_node.to_bytes()?;
        let new_node_hash = Digest::hash(&new_node_bytes);
        let parent_extension = Trie::extension(
            parent_extension_affix.to_vec(),
            Pointer::NodePointer(new_node_hash),
        );
        parents.push((parent_extension_affix[0], parent_extension));
    }
    Ok(SplitResult {
        new_node,
        parents,
        maybe_hashed_child_extension,
    })
}
fn split_extension < K , V > ( new_leaf_path : & [ u8 ] , existing_extension : Trie < K , V > , mut parents : Parents < K , V > , ) -> Result < SplitResult < K , V > , bytesrepr :: Error > where K : ToBytes + Clone , V : ToBytes + Clone , { // TODO: add is_extension() method to Trie let ( affix , pointer ) = match existing_extension { Trie :: Extension { affix , pointer } => ( affix , pointer ) , _ => panic ! ( " " ) , } ; let parents_path = get_parents_path ( & parents ) ; // Get the path to the existing extension node let existing_extension_path : Vec < u8 > = parents_path . iter ( ) . chain ( affix . iter ( ) ) . cloned ( ) . collect ( ) ; // Get the path that the new leaf and existing leaf share let shared_path = common_prefix ( new_leaf_path , & existing_extension_path ) ; // Create an affix for a possible parent extension above the new // node. let parent_extension_affix = shared_path [ parents_path . len ( ) .. ] . to_vec ( ) ; // Create an affix for a possible child extension between the new // node and the node that the existing extension pointed to. let child_extension_affix = affix [ parent_extension_affix . len ( ) + 1 .. ] . to_vec ( ) ; // Create a child extension (paired with its hash) if necessary let maybe_hashed_child_extension : Option < ( Digest , Trie < K , V > ) > = if child_extension_affix . is_empty ( ) { None } else { let child_extension = Trie :: extension ( child_extension_affix . to_vec ( ) , pointer ) ; let child_extension_bytes = child_extension . to_bytes ( ) ? ; let child_extension_hash = Digest :: hash ( & child_extension_bytes ) ; Some ( ( child_extension_hash , child_extension ) ) } ; // Assemble a new node. let new_node : Trie < K , V > = { let index = existing_extension_path [ shared_path . len ( ) ] ; let pointer = maybe_hashed_child_extension . to_owned ( ) . map_or ( pointer , | ( hash , _ ) | Pointer :: NodePointer ( hash ) ) ; Trie :: node ( & [ ( index , pointer ) ] ) } ; // Create a parent extension if necessary if ! parent_extension_affix . is_empty ( ) { let new_node_bytes = new_node . to_bytes ( ) ? ; let new_node_hash = Digest :: hash ( & new_node_bytes ) ; let parent_extension = Trie :: extension ( parent_extension_affix . to_vec ( ) , Pointer :: NodePointer ( new_node_hash ) , ) ; parents . push ( ( parent_extension_affix [ 0 ] , parent_extension ) ) ; } Ok ( SplitResult { new_node , parents , maybe_hashed_child_extension , } ) }
Takes a path to a new leaf, an existing extension that leaf collides with,
and the parents of that extension.
Takes a path to a new leaf an existing extension that leaf collides with and the parents of that extension .
new_leaf_path
&[u8]
existing_extension
Trie<K, V>
parents
Parents<K, V>
new_leaf_path
&[u8]
existing_extension
Trie<K, V>
parents
Parents<K, V>