pub fn update(
        &self,
        state_changes: &[StateChange],
        is_virtual: bool,
    ) -> Result<String, StateDatabaseError> {
        let mut path_map = HashMap::new();

        let mut deletions = HashSet::new();
        let mut additions = HashSet::new();

        let mut delete_items = vec![];
        for state_change in state_changes {
            match state_change {
                StateChange::Set { key, value } => {
                    let tokens = tokenize_address(key);
                    let mut set_path_map = self.get_path_by_tokens(&tokens, false)?;
                    {
                        let node = set_path_map
                            .get_mut(key)
                            .expect("Path map not correctly generated");
                        node.value = Some(value.to_vec());
                    }
                    for pkey in set_path_map.keys() {
                        additions.insert(pkey.clone());
                    }
                    path_map.extend(set_path_map);
                }
                StateChange::Delete { key } => {
                    let tokens = tokenize_address(key);
                    let del_path_map = self.get_path_by_tokens(&tokens, true)?;
                    path_map.extend(del_path_map);
                    delete_items.push(key);
                }
            }
        }

        for del_address in delete_items.iter() {
            path_map.remove(*del_address);
            let (mut parent_address, mut path_branch) = parent_and_branch(del_address);
            while parent_address != "" {
                let remove_parent = {
                    let parent_node = path_map
                        .get_mut(parent_address)
                        .expect("Path map not correctly generated or entry is deleted");

                    if let Some(old_hash_key) = parent_node.children.remove(path_branch) {
                        deletions.insert(old_hash_key);
                    }

                    parent_node.children.is_empty()
                };

                // there's no children to the parent node already in the tree, remove it from
                // path_map if a new node doesn't have this as its parent
                if remove_parent && !additions.contains(parent_address) {
                    // empty node delete it.
                    path_map.remove(parent_address);
                } else {
                    // found a node that is not empty no need to continue
                    break;
                }

                let (next_parent, next_branch) = parent_and_branch(parent_address);
                parent_address = next_parent;
                path_branch = next_branch;

                if parent_address == "" {
                    let parent_node = path_map
                        .get_mut(parent_address)
                        .expect("Path map not correctly generated");

                    if let Some(old_hash_key) = parent_node.children.remove(path_branch) {
                        deletions.insert(old_hash_key);
                    }
                }
            }
        }

        let mut sorted_paths: Vec<_> = path_map.keys().cloned().collect();
        // Sort by longest to shortest
        sorted_paths.sort_by(|a, b| b.len().cmp(&a.len()));

        // initializing this to empty, to make the compiler happy
        let mut key_hash = Vec::with_capacity(0);
        let mut batch = Vec::with_capacity(sorted_paths.len());
        for path in sorted_paths {
            let node = path_map
                .remove(&path)
                .expect("Path map keys are out of sink");
            let (hash_key, packed) = encode_and_hash(node)?;
            key_hash = hash_key.clone();

            if path != "" {
                let (parent_address, path_branch) = parent_and_branch(&path);
                let parent = path_map
                    .get_mut(parent_address)
                    .expect("Path map not correctly generated");
                if let Some(old_hash_key) = parent
                    .children
                    .insert(path_branch.to_string(), ::hex::encode(hash_key.clone()))
                {
                    deletions.insert(old_hash_key);
                }
            }

            batch.push((hash_key, packed));
        }

        if !is_virtual {
            let deletions: Vec<Vec<u8>> = deletions
                .iter()
                // We expect this to be hex, since we generated it
                .map(|s| ::hex::decode(s).expect("Improper hex"))
                .collect();
            self.store_changes(&key_hash, &batch, &deletions)?;
        }

        Ok(::hex::encode(key_hash))
    }
/// Updates the tree with multiple changes.  Applies both set and deletes,
/// as given.
///
/// If the flag `is_virtual` is set, the values are not written to the
/// underlying database.
///
/// Returns a Result with the new root hash.
Updates the tree with multiple changes.  Applies both set and deletes,
as given.

If the flag `is_virtual` is set, the values are not written to the
underlying database.

Returns a Result with the new root hash.
Updates the tree with multiple changes . Applies both set and deletes as given . If the flag ` is_virtual ` is set the values are not written to the underlying database . Returns a Result with the new root hash .
pub fn update(
        &self,
        state_changes: &[StateChange],
        is_virtual: bool,
    ) -> Result<String, StateDatabaseError> {
        let mut path_map = HashMap::new();
        let mut deletions = HashSet::new();
        let mut additions = HashSet::new();
        let mut delete_items = vec![];
        for state_change in state_changes {
            match state_change {
                StateChange::Set { key, value } => {
                    let tokens = tokenize_address(key);
                    let mut set_path_map = self.get_path_by_tokens(&tokens, false)?;
                    {
                        let node = set_path_map
                            .get_mut(key)
                            .expect("Path map not correctly generated");
                        node.value = Some(value.to_vec());
                    }
                    for pkey in set_path_map.keys() {
                        additions.insert(pkey.clone());
                    }
                    path_map.extend(set_path_map);
                }
                StateChange::Delete { key } => {
                    let tokens = tokenize_address(key);
                    let del_path_map = self.get_path_by_tokens(&tokens, true)?;
                    path_map.extend(del_path_map);
                    delete_items.push(key);
                }
            }
        }
        for del_address in delete_items.iter() {
            path_map.remove(*del_address);
            let (mut parent_address, mut path_branch) = parent_and_branch(del_address);
            while parent_address != "" {
                let remove_parent = {
                    let parent_node = path_map
                        .get_mut(parent_address)
                        .expect("Path map not correctly generated or entry is deleted");
                    if let Some(old_hash_key) = parent_node.children.remove(path_branch) {
                        deletions.insert(old_hash_key);
                    }
                    parent_node.children.is_empty()
                };
                // there's no children to the parent node already in the tree, remove it from
                // path_map if a new node doesn't have this as its parent
                if remove_parent && !additions.contains(parent_address) {
                    // empty node delete it.
                    path_map.remove(parent_address);
                } else {
                    // found a node that is not empty no need to continue
                    break;
                }
                let (next_parent, next_branch) = parent_and_branch(parent_address);
                parent_address = next_parent;
                path_branch = next_branch;
                if parent_address == "" {
                    let parent_node = path_map
                        .get_mut(parent_address)
                        .expect("Path map not correctly generated");
                    if let Some(old_hash_key) = parent_node.children.remove(path_branch) {
                        deletions.insert(old_hash_key);
                    }
                }
            }
        }
        let mut sorted_paths: Vec<_> = path_map.keys().cloned().collect();
        // Sort by longest to shortest
        sorted_paths.sort_by(|a, b| b.len().cmp(&a.len()));
        // initializing this to empty, to make the compiler happy
        let mut key_hash = Vec::with_capacity(0);
        let mut batch = Vec::with_capacity(sorted_paths.len());
        for path in sorted_paths {
            let node = path_map
                .remove(&path)
                .expect("Path map keys are out of sink");
            let (hash_key, packed) = encode_and_hash(node)?;
            key_hash = hash_key.clone();
            if path != "" {
                let (parent_address, path_branch) = parent_and_branch(&path);
                let parent = path_map
                    .get_mut(parent_address)
                    .expect("Path map not correctly generated");
                if let Some(old_hash_key) = parent
                    .children
                    .insert(path_branch.to_string(), ::hex::encode(hash_key.clone()))
                {
                    deletions.insert(old_hash_key);
                }
            }
            batch.push((hash_key, packed));
        }
        if !is_virtual {
            let deletions: Vec<Vec<u8>> = deletions
                .iter()
                // We expect this to be hex, since we generated it
                .map(|s| ::hex::decode(s).expect("Improper hex"))
                .collect();
            self.store_changes(&key_hash, &batch, &deletions)?;
        }
        Ok(::hex::encode(key_hash))
    }
pub fn update ( & self , state_changes : & [ StateChange ] , is_virtual : bool , ) -> Result < String , StateDatabaseError > { let mut path_map = HashMap :: new ( ) ; let mut deletions = HashSet :: new ( ) ; let mut additions = HashSet :: new ( ) ; let mut delete_items = vec ! [ ] ; for state_change in state_changes { match state_change { StateChange :: Set { key , value } => { let tokens = tokenize_address ( key ) ; let mut set_path_map = self . get_path_by_tokens ( & tokens , false ) ? ; { let node = set_path_map . get_mut ( key ) . expect ( " " ) ; node . value = Some ( value . to_vec ( ) ) ; } for pkey in set_path_map . keys ( ) { additions . insert ( pkey . clone ( ) ) ; } path_map . extend ( set_path_map ) ; } StateChange :: Delete { key } => { let tokens = tokenize_address ( key ) ; let del_path_map = self . get_path_by_tokens ( & tokens , true ) ? ; path_map . extend ( del_path_map ) ; delete_items . push ( key ) ; } } } for del_address in delete_items . iter ( ) { path_map . remove ( * del_address ) ; let ( mut parent_address , mut path_branch ) = parent_and_branch ( del_address ) ; while parent_address != " " { let remove_parent = { let parent_node = path_map . get_mut ( parent_address ) . expect ( " " ) ; if let Some ( old_hash_key ) = parent_node . children . remove ( path_branch ) { deletions . insert ( old_hash_key ) ; } parent_node . children . is_empty ( ) } ; // there's no children to the parent node already in the tree, remove it from // path_map if a new node doesn't have this as its parent if remove_parent && ! additions . contains ( parent_address ) { // empty node delete it. path_map . remove ( parent_address ) ; } else { // found a node that is not empty no need to continue break ; } let ( next_parent , next_branch ) = parent_and_branch ( parent_address ) ; parent_address = next_parent ; path_branch = next_branch ; if parent_address == " " { let parent_node = path_map . get_mut ( parent_address ) . expect ( " " ) ; if let Some ( old_hash_key ) = parent_node . children . remove ( path_branch ) { deletions . insert ( old_hash_key ) ; } } } } let mut sorted_paths : Vec < _ > = path_map . keys ( ) . cloned ( ) . collect ( ) ; // Sort by longest to shortest sorted_paths . sort_by ( | a , b | b . len ( ) . cmp ( & a . len ( ) ) ) ; // initializing this to empty, to make the compiler happy let mut key_hash = Vec :: with_capacity ( 0 ) ; let mut batch = Vec :: with_capacity ( sorted_paths . len ( ) ) ; for path in sorted_paths { let node = path_map . remove ( & path ) . expect ( " " ) ; let ( hash_key , packed ) = encode_and_hash ( node ) ? ; key_hash = hash_key . clone ( ) ; if path != " " { let ( parent_address , path_branch ) = parent_and_branch ( & path ) ; let parent = path_map . get_mut ( parent_address ) . expect ( " " ) ; if let Some ( old_hash_key ) = parent . children . insert ( path_branch . to_string ( ) , :: hex :: encode ( hash_key . clone ( ) ) ) { deletions . insert ( old_hash_key ) ; } } batch . push ( ( hash_key , packed ) ) ; } if ! is_virtual { let deletions : Vec < Vec < u8 > > = deletions . iter ( ) // We expect this to be hex, since we generated it . map ( | s | :: hex :: decode ( s ) . expect ( " " ) ) . collect ( ) ; self . store_changes ( & key_hash , & batch , & deletions ) ? ; } Ok ( :: hex :: encode ( key_hash ) ) }
Updates the tree with multiple changes.
Updates the tree with multiple changes .
&self
state_changes
&[StateChange]
is_virtual
bool
&self
state_changes
&[StateChange]
is_virtual
bool