diff --git a/core/store/src/trie/mem/mem_trie_update.rs b/core/store/src/trie/mem/mem_trie_update.rs index 2257e5d0c21..dcd0d5b1f0a 100644 --- a/core/store/src/trie/mem/mem_trie_update.rs +++ b/core/store/src/trie/mem/mem_trie_update.rs @@ -6,8 +6,8 @@ use near_primitives::state::FlatStateValue; use crate::trie::ops::insert_delete::GenericTrieUpdateInsertDelete; use crate::trie::ops::interface::{ - GenericNodeOrIndex, GenericTrieUpdate, GenericTrieValue, GenericUpdatedNodeId, - GenericUpdatedTrieNode, GenericUpdatedTrieNodeWithSize, + GenericNodeOrIndex, GenericTrieNode, GenericTrieNodeWithSize, GenericTrieUpdate, + GenericTrieValue, GenericUpdatedTrieNode, GenericUpdatedTrieNodeWithSize, UpdatedNodeId, }; use crate::trie::trie_recording::TrieRecorder; use crate::trie::{Children, MemTrieChanges, TrieRefcountDeltaMap}; @@ -18,37 +18,37 @@ use super::flexible_data::children::ChildrenView; use super::metrics::MEM_TRIE_NUM_NODES_CREATED_FROM_UPDATES; use super::node::{InputMemTrieNode, MemTrieNodeId, MemTrieNodeView}; -pub type UpdatedMemTrieNodeId = usize; - pub type OldOrUpdatedNodeId = GenericNodeOrIndex; +pub type MemTrieNode = GenericTrieNode; + pub type UpdatedMemTrieNode = GenericUpdatedTrieNode; +pub type MemTrieNodeWithSize = GenericTrieNodeWithSize; + pub type UpdatedMemTrieNodeWithSize = GenericUpdatedTrieNodeWithSize; -impl UpdatedMemTrieNodeWithSize { +impl MemTrieNodeWithSize { /// Converts an existing in-memory trie node into an updated one that is /// equivalent. pub fn from_existing_node_view<'a, M: ArenaMemory>(view: MemTrieNodeView<'a, M>) -> Self { let memory_usage = view.memory_usage(); let node = match view { - MemTrieNodeView::Leaf { extension, value } => UpdatedMemTrieNode::Leaf { + MemTrieNodeView::Leaf { extension, value } => MemTrieNode::Leaf { extension: extension.to_vec().into_boxed_slice(), value: value.to_flat_value(), }, - MemTrieNodeView::Branch { children, .. } => UpdatedMemTrieNode::Branch { + MemTrieNodeView::Branch { children, .. } => MemTrieNode::Branch { children: Box::new(Self::convert_children_to_updated(children)), value: None, }, - MemTrieNodeView::BranchWithValue { children, value, .. } => { - UpdatedMemTrieNode::Branch { - children: Box::new(Self::convert_children_to_updated(children)), - value: Some(value.to_flat_value()), - } - } - MemTrieNodeView::Extension { extension, child, .. } => UpdatedMemTrieNode::Extension { + MemTrieNodeView::BranchWithValue { children, value, .. } => MemTrieNode::Branch { + children: Box::new(Self::convert_children_to_updated(children)), + value: Some(value.to_flat_value()), + }, + MemTrieNodeView::Extension { extension, child, .. } => MemTrieNode::Extension { extension: extension.to_vec().into_boxed_slice(), - child: OldOrUpdatedNodeId::Old(child.id()), + child: child.id(), }, }; Self { node, memory_usage } @@ -56,11 +56,11 @@ impl UpdatedMemTrieNodeWithSize { fn convert_children_to_updated<'a, M: ArenaMemory>( view: ChildrenView<'a, M>, - ) -> [Option; 16] { + ) -> [Option; 16] { let mut children = [None; 16]; for i in 0..16 { if let Some(child) = view.get(i) { - children[i] = Some(OldOrUpdatedNodeId::Old(child.id())); + children[i] = Some(child.id()); } } children @@ -152,27 +152,27 @@ impl<'a, M: ArenaMemory> GenericTrieUpdate<'a, MemTrieNodeId, FlatStateValue> fn ensure_updated( &mut self, node: GenericNodeOrIndex, - ) -> Result { + ) -> Result { Ok(match node { GenericNodeOrIndex::Old(node_id) => self.convert_existing_to_updated(Some(node_id)), GenericNodeOrIndex::Updated(node_id) => node_id, }) } - fn take_node(&mut self, index: UpdatedMemTrieNodeId) -> UpdatedMemTrieNodeWithSize { + fn take_node(&mut self, index: UpdatedNodeId) -> UpdatedMemTrieNodeWithSize { self.updated_nodes.get_mut(index).unwrap().take().expect("Node taken twice") } - fn place_node_at(&mut self, index: UpdatedMemTrieNodeId, node: UpdatedMemTrieNodeWithSize) { + fn place_node_at(&mut self, index: UpdatedNodeId, node: UpdatedMemTrieNodeWithSize) { assert!(self.updated_nodes[index].is_none(), "Node placed twice"); self.updated_nodes[index] = Some(node); } - fn get_node_ref(&self, node_id: GenericUpdatedNodeId) -> &UpdatedMemTrieNodeWithSize { + fn get_node_ref(&self, node_id: UpdatedNodeId) -> &UpdatedMemTrieNodeWithSize { self.updated_nodes[node_id].as_ref().unwrap() } - fn place_node(&mut self, node: UpdatedMemTrieNodeWithSize) -> GenericUpdatedNodeId { + fn place_node(&mut self, node: UpdatedMemTrieNodeWithSize) -> UpdatedNodeId { let index = self.updated_nodes.len(); self.updated_nodes.push(Some(node)); index @@ -232,7 +232,7 @@ impl<'a, M: ArenaMemory> MemTrieUpdate<'a, M> { } /// Creates a new updated node, assigning it a new ID. - fn new_updated_node(&mut self, node: UpdatedMemTrieNodeWithSize) -> UpdatedMemTrieNodeId { + fn new_updated_node(&mut self, node: UpdatedMemTrieNodeWithSize) -> UpdatedNodeId { let index = self.updated_nodes.len(); self.updated_nodes.push(Some(node)); index @@ -245,7 +245,7 @@ impl<'a, M: ArenaMemory> MemTrieUpdate<'a, M> { /// /// If the original node is None, it is a marker for the root of an empty /// trie. - fn convert_existing_to_updated(&mut self, node: Option) -> UpdatedMemTrieNodeId { + fn convert_existing_to_updated(&mut self, node: Option) -> UpdatedNodeId { let Some(node) = node else { return self.new_updated_node(UpdatedMemTrieNodeWithSize::empty()); }; @@ -253,7 +253,7 @@ impl<'a, M: ArenaMemory> MemTrieUpdate<'a, M> { if let Some(tracked_trie_changes) = self.nodes_tracker.as_mut() { tracked_trie_changes.record(&node_view); } - self.new_updated_node(UpdatedMemTrieNodeWithSize::from_existing_node_view(node_view)) + self.new_updated_node(MemTrieNodeWithSize::from_existing_node_view(node_view).into()) } /// Inserts the given key value pair into the trie. @@ -279,9 +279,9 @@ impl<'a, M: ArenaMemory> MemTrieUpdate<'a, M> { /// updated nodes. After this function, `ordered_nodes` contains the IDs of /// the updated nodes in the order they should be created. fn post_order_traverse_updated_nodes( - node_id: UpdatedMemTrieNodeId, + node_id: UpdatedNodeId, updated_nodes: &Vec>, - ordered_nodes: &mut Vec, + ordered_nodes: &mut Vec, ) { let node = updated_nodes[node_id].as_ref().unwrap(); match &node.node { @@ -320,9 +320,9 @@ impl<'a, M: ArenaMemory> MemTrieUpdate<'a, M> { /// `updated_nodes` must be indexed by the node IDs in `ordered_nodes`. pub(crate) fn compute_hashes_and_serialized_nodes( &self, - ordered_nodes: &Vec, + ordered_nodes: &Vec, updated_nodes: &Vec>, - ) -> Vec<(UpdatedMemTrieNodeId, CryptoHash, Vec)> { + ) -> Vec<(UpdatedNodeId, CryptoHash, Vec)> { let memory = self.memory; let mut result = Vec::<(CryptoHash, Vec)>::new(); for _ in 0..updated_nodes.len() { @@ -459,7 +459,7 @@ pub(super) fn construct_root_from_changes( ) -> Option { let mut last_node_id: Option = None; let map_to_new_node_id = |node_id: OldOrUpdatedNodeId, - old_to_new_map: &HashMap| + old_to_new_map: &HashMap| -> MemTrieNodeId { match node_id { OldOrUpdatedNodeId::Updated(node_id) => *old_to_new_map.get(&node_id).unwrap(), @@ -467,7 +467,7 @@ pub(super) fn construct_root_from_changes( } }; - let mut updated_to_new_map = HashMap::::new(); + let mut updated_to_new_map = HashMap::::new(); let updated_nodes = &changes.updated_nodes; let node_ids_with_hashes = &changes.node_ids_with_hashes; for (node_id, node_hash) in node_ids_with_hashes.iter() { diff --git a/core/store/src/trie/mod.rs b/core/store/src/trie/mod.rs index 5437d7eea57..cfdc3668e4d 100644 --- a/core/store/src/trie/mod.rs +++ b/core/store/src/trie/mod.rs @@ -18,7 +18,7 @@ pub use crate::trie::trie_storage::{TrieCache, TrieCachingStorage, TrieDBStorage use crate::StorageError; use borsh::{BorshDeserialize, BorshSerialize}; pub use from_flat::construct_trie_from_flat; -use mem::mem_trie_update::{TrackingMode, UpdatedMemTrieNodeId, UpdatedMemTrieNodeWithSize}; +use mem::mem_trie_update::{TrackingMode, UpdatedMemTrieNodeWithSize}; use mem::mem_tries::MemTries; use near_primitives::challenge::PartialState; use near_primitives::hash::{hash, CryptoHash}; @@ -31,9 +31,9 @@ use near_primitives::types::{AccountId, StateRoot, StateRootNode}; use near_schema_checker_lib::ProtocolSchema; use near_vm_runner::ContractCode; use ops::insert_delete::GenericTrieUpdateInsertDelete; -use ops::interface::GenericTrieValue; #[cfg(test)] -use ops::interface::{GenericNodeOrIndex, GenericTrieUpdate}; +use ops::interface::{GenericNodeOrIndex, GenericTrieNode, GenericTrieUpdate}; +use ops::interface::{GenericTrieValue, UpdatedNodeId}; pub use raw_node::{Children, RawTrieNode, RawTrieNodeWithSize}; use std::cell::RefCell; use std::collections::{BTreeMap, HashSet}; @@ -43,9 +43,9 @@ use std::ops::DerefMut; use std::str; use std::sync::{Arc, RwLock, RwLockReadGuard}; pub use trie_recording::{SubtreeSize, TrieRecorder, TrieRecorderStats}; -#[cfg(test)] -use trie_storage_update::UpdatedTrieStorageNode; -use trie_storage_update::{TrieStorageUpdate, UpdatedTrieStorageNodeWithSize}; +use trie_storage_update::{ + TrieStorageNodeWithSize, TrieStorageUpdate, UpdatedTrieStorageNodeWithSize, +}; pub mod accounting_cache; mod config; @@ -198,14 +198,14 @@ impl UpdatedTrieStorageNodeWithSize { spaces: &mut String, ) -> std::fmt::Result { match &self.node { - UpdatedTrieStorageNode::Empty => { + GenericTrieNode::Empty => { write!(f, "{}Empty", spaces)?; } - UpdatedTrieStorageNode::Leaf { extension, .. } => { + GenericTrieNode::Leaf { extension, .. } => { let slice = NibbleSlice::from_encoded(&extension); write!(f, "{}Leaf({:?}, val)", spaces, slice.0)?; } - UpdatedTrieStorageNode::Branch { children, value } => { + GenericTrieNode::Branch { children, value } => { writeln!( f, "{}Branch({}){{", @@ -232,7 +232,7 @@ impl UpdatedTrieStorageNodeWithSize { spaces.remove(spaces.len() - 1); write!(f, "{}}}", spaces)?; } - UpdatedTrieStorageNode::Extension { extension, child } => { + GenericTrieNode::Extension { extension, child } => { let slice = NibbleSlice::from_encoded(&extension); writeln!(f, "{}Extension({:?})", spaces, slice)?; spaces.push(' '); @@ -533,7 +533,7 @@ pub struct MemTrieChanges { /// Node ids with hashes of updated nodes. /// Should be in the post-order traversal of the updated nodes. /// It implies that the root node is the last one in the list. - node_ids_with_hashes: Vec<(UpdatedMemTrieNodeId, CryptoHash)>, + node_ids_with_hashes: Vec<(UpdatedNodeId, CryptoHash)>, updated_nodes: Vec>, } @@ -771,7 +771,7 @@ impl Trie { trie } - /// Get statisitics about the recorded trie. Useful for observability and debugging. + /// Get statistics about the recorded trie. Useful for observability and debugging. /// This scans all of the recorded data, so could potentially be expensive to run. pub fn recorder_stats(&self) -> Option { self.recorder.as_ref().map(|recorder| recorder.borrow().get_stats(&self.root)) @@ -882,15 +882,15 @@ impl Trie { .expect("storage failure") .expect("node cannot be Empty") .1; - UpdatedTrieStorageNodeWithSize::from_raw_trie_node_with_size(raw_node) + TrieStorageNodeWithSize::from_raw_trie_node_with_size(raw_node).into() } }; let mut memory_usage_naive = node.memory_usage_direct(); match &node { - UpdatedTrieStorageNode::Empty => {} - UpdatedTrieStorageNode::Leaf { .. } => {} - UpdatedTrieStorageNode::Branch { children, .. } => { + GenericTrieNode::Empty => {} + GenericTrieNode::Leaf { .. } => {} + GenericTrieNode::Branch { children, .. } => { memory_usage_naive += children .iter() .filter_map(|handle| { @@ -898,7 +898,7 @@ impl Trie { }) .sum::(); } - UpdatedTrieStorageNode::Extension { child, .. } => { + GenericTrieNode::Extension { child, .. } => { memory_usage_naive += self.memory_usage_verify(trie_update, *child); } }; @@ -1253,7 +1253,7 @@ impl Trie { None => Ok(trie_update.store(UpdatedTrieStorageNodeWithSize::empty())), Some((_, node)) => { let result = trie_update - .store(UpdatedTrieStorageNodeWithSize::from_raw_trie_node_with_size(node)); + .store(TrieStorageNodeWithSize::from_raw_trie_node_with_size(node).into()); trie_update.refcount_changes.subtract(*hash, 1); Ok(result) } diff --git a/core/store/src/trie/ops/insert_delete.rs b/core/store/src/trie/ops/insert_delete.rs index c49b42fd547..0e8fae744c5 100644 --- a/core/store/src/trie/ops/insert_delete.rs +++ b/core/store/src/trie/ops/insert_delete.rs @@ -3,8 +3,8 @@ use near_primitives::errors::StorageError; use crate::NibbleSlice; use super::interface::{ - GenericNodeOrIndex, GenericTrieUpdate, GenericTrieValue, GenericUpdatedNodeId, - GenericUpdatedTrieNode, GenericUpdatedTrieNodeWithSize, HasValueLength, + GenericNodeOrIndex, GenericTrieUpdate, GenericTrieValue, GenericUpdatedTrieNode, + GenericUpdatedTrieNodeWithSize, HasValueLength, UpdatedNodeId, }; use super::squash::GenericTrieUpdateSquash; @@ -16,10 +16,10 @@ where { fn calc_memory_usage_and_store( &mut self, - node_id: GenericUpdatedNodeId, + node_id: UpdatedNodeId, children_memory_usage: u64, new_node: GenericUpdatedTrieNode, - old_child: Option, + old_child: Option, ) { let new_memory_usage = children_memory_usage.saturating_add(new_node.memory_usage_direct()).saturating_sub( @@ -38,7 +38,7 @@ where /// created nodes - that's done at the end. fn generic_insert( &mut self, - mut node_id: GenericUpdatedNodeId, + mut node_id: UpdatedNodeId, key: &[u8], value: GenericTrieValue, ) -> Result<(), StorageError> { @@ -304,7 +304,7 @@ where /// Deleting a non-existent key is allowed, and is a no-op. fn generic_delete( &mut self, - mut node_id: GenericUpdatedNodeId, + mut node_id: UpdatedNodeId, key: &[u8], ) -> Result<(), StorageError> { let mut partial = NibbleSlice::new(key); diff --git a/core/store/src/trie/ops/interface.rs b/core/store/src/trie/ops/interface.rs index 86389b3e97f..fc2b4a695b6 100644 --- a/core/store/src/trie/ops/interface.rs +++ b/core/store/src/trie/ops/interface.rs @@ -4,7 +4,7 @@ use near_primitives::state::FlatStateValue; use crate::trie::{ValueHandle, TRIE_COSTS}; /// For updated nodes, the ID is simply the index into the array of updated nodes we keep. -pub type GenericUpdatedNodeId = usize; +pub type UpdatedNodeId = usize; /// Value to insert to trie or update existing value in the trie. #[derive(Debug, Clone)] @@ -37,18 +37,22 @@ impl HasValueLength for ValueHandle { } } -/// An old node means a node in the current in-memory trie. An updated node means a -/// node we're going to store in the in-memory trie but have not constructed there yet. +/// This enum represents pointer to a node in trie or pointer to an updated node in trie. +/// +/// An old node is the pointer to a node currently in trie. +/// An updated node is the index in the TrieUpdate struct where we temporarily store updates +/// These eventually get written back to the trie during finalization and commit of trie update. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GenericNodeOrIndex { Old(GenericTrieNodePtr), - Updated(GenericUpdatedNodeId), + Updated(UpdatedNodeId), } -/// An updated node - a node that will eventually become a trie node. -/// It references children that are either old or updated nodes. +/// A generic representation of a trie node +/// TrieNodePtr can potentially be of any type including GenericTrieNodePtr for normal nodes or +/// GenericNodeOrIndex for updated nodes. #[derive(Debug, Clone, PartialEq, Eq)] -pub enum GenericUpdatedTrieNode { +pub enum GenericTrieNode { /// Used for either an empty root node (indicating an empty trie), or as a temporary /// node to ease implementation. Empty, @@ -58,19 +62,18 @@ pub enum GenericUpdatedTrieNode { }, Extension { extension: Box<[u8]>, - child: GenericNodeOrIndex, + child: TrieNodePtr, }, /// Corresponds to either a Branch or BranchWithValue node. Branch { - children: Box<[Option>; 16]>, + children: Box<[Option; 16]>, value: Option, }, } -impl - GenericUpdatedTrieNode +impl GenericTrieNode where - GenericValueHandle: HasValueLength, + V: HasValueLength, { fn memory_usage_value(value_length: u64) -> u64 { value_length * TRIE_COSTS.byte_of_value + TRIE_COSTS.node_cost @@ -102,6 +105,37 @@ where } } +/// An updated node - a node that will eventually become a trie node. +/// It references children that are of type GenericNodeOrIndex +/// i.e. either old nodes or updated nodes. +pub type GenericUpdatedTrieNode = + GenericTrieNode, GenericValueHandle>; + +/// Simple conversion from GenericTrieNode to GenericUpdatedTrieNode +/// We change all occurrences of GenericTrieNodePtr to GenericNodeOrIndex::Old(ptr) +impl From> for GenericUpdatedTrieNode { + fn from(node: GenericTrieNode) -> Self { + match node { + GenericTrieNode::Empty => Self::Empty, + GenericTrieNode::Leaf { extension, value } => Self::Leaf { extension, value }, + GenericTrieNode::Extension { extension, child } => { + Self::Extension { extension, child: GenericNodeOrIndex::Old(child) } + } + GenericTrieNode::Branch { children, value } => { + let children = Box::new(children.map(|child| child.map(GenericNodeOrIndex::Old))); + Self::Branch { children, value } + } + } + } +} + +/// A trie node with its memory usage. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GenericTrieNodeWithSize { + pub node: GenericTrieNode, + pub memory_usage: u64, +} + /// An updated node with its memory usage. /// Needed to recompute subtree function (memory usage) on the fly. #[derive(Debug, Clone, PartialEq, Eq)] @@ -116,6 +150,12 @@ impl GenericUpdatedTrieNodeWithSize { } } +impl From> for GenericUpdatedTrieNodeWithSize { + fn from(node: GenericTrieNodeWithSize) -> Self { + Self { node: node.node.into(), memory_usage: node.memory_usage } + } +} + /// Trait for trie updates to handle updated nodes. /// /// So far, this is used to handle key-value insertions, deletions and range @@ -125,20 +165,20 @@ impl GenericUpdatedTrieNodeWithSize { /// `GenericTrieUpdate` abstracts the storage of updated nodes for the original /// node type `GenericTrieNodePtr`. /// -/// In this storage, nodes are indexed by `GenericUpdatedNodeId`. +/// In this storage, nodes are indexed by `UpdatedNodeId`. /// Node is stored as `GenericUpdatedTrieNodeWithSize`, which stores children /// as `GenericNodeOrIndex`. Each child may be either an old node or an updated /// node. /// /// The flow of interaction with this storage is: /// - In the beginning, call `ensure_updated` for the -/// `GenericNodeOrIndex::Old(root_node)` which returns `GenericUpdatedNodeId`, +/// `GenericNodeOrIndex::Old(root_node)` which returns `UpdatedNodeId`, /// it should be zero. /// - For every update (single insert, single delete, recursive range -/// operation...), call corresponding method with `GenericUpdatedNodeId` for +/// operation...), call corresponding method with `UpdatedNodeId` for /// the root. /// - Then, we hold the invariant that on every descent we have -/// `GenericUpdatedNodeId`. +/// `UpdatedNodeId`. /// - So, first, we call `take_node` to get `GenericUpdatedTrieNodeWithSize` /// back; /// - We possibly descend into its children and modify the node; @@ -157,21 +197,21 @@ pub(crate) trait GenericTrieUpdate<'a, GenericTrieNodePtr, GenericValueHandle> { fn ensure_updated( &mut self, node: GenericNodeOrIndex, - ) -> Result; + ) -> Result; /// Takes a node from the set of updated nodes, setting it to None. /// It is expected that place_node is then called to return the node to /// the same slot. fn take_node( &mut self, - node_id: GenericUpdatedNodeId, + node_id: UpdatedNodeId, ) -> GenericUpdatedTrieNodeWithSize; /// Puts a node to the set of updated nodes at specific index. /// Needed when reference to node from parent needs to be preserved. fn place_node_at( &mut self, - node_id: GenericUpdatedNodeId, + node_id: UpdatedNodeId, node: GenericUpdatedTrieNodeWithSize, ); @@ -179,12 +219,12 @@ pub(crate) trait GenericTrieUpdate<'a, GenericTrieNodePtr, GenericValueHandle> { fn place_node( &mut self, node: GenericUpdatedTrieNodeWithSize, - ) -> GenericUpdatedNodeId; + ) -> UpdatedNodeId; /// Gets a node reference in the set of updated nodes. fn get_node_ref( &self, - node_id: GenericUpdatedNodeId, + node_id: UpdatedNodeId, ) -> &GenericUpdatedTrieNodeWithSize; /// Stores a state value in the trie. diff --git a/core/store/src/trie/ops/resharding.rs b/core/store/src/trie/ops/resharding.rs index a2f1c0d2603..4f9f68533f5 100644 --- a/core/store/src/trie/ops/resharding.rs +++ b/core/store/src/trie/ops/resharding.rs @@ -8,8 +8,8 @@ use near_primitives::types::AccountId; use crate::NibbleSlice; use super::interface::{ - GenericNodeOrIndex, GenericTrieUpdate, GenericUpdatedNodeId, GenericUpdatedTrieNode, - GenericUpdatedTrieNodeWithSize, HasValueLength, + GenericNodeOrIndex, GenericTrieUpdate, GenericUpdatedTrieNode, GenericUpdatedTrieNodeWithSize, + HasValueLength, UpdatedNodeId, }; use super::squash::GenericTrieUpdateSquash; @@ -78,7 +78,7 @@ where /// `intervals_nibbles` is the list of ranges to be retained. fn retain_multi_range_recursive( &mut self, - node_id: GenericUpdatedNodeId, + node_id: UpdatedNodeId, key_nibbles: Vec, intervals_nibbles: &[Range>], ) -> Result<(), StorageError> { diff --git a/core/store/src/trie/ops/squash.rs b/core/store/src/trie/ops/squash.rs index 5c0d86cf0b6..7189419a830 100644 --- a/core/store/src/trie/ops/squash.rs +++ b/core/store/src/trie/ops/squash.rs @@ -3,8 +3,8 @@ use near_primitives::errors::StorageError; use crate::NibbleSlice; use super::interface::{ - GenericNodeOrIndex, GenericTrieUpdate, GenericUpdatedNodeId, GenericUpdatedTrieNode, - GenericUpdatedTrieNodeWithSize, HasValueLength, + GenericNodeOrIndex, GenericTrieUpdate, GenericUpdatedTrieNode, GenericUpdatedTrieNodeWithSize, + HasValueLength, UpdatedNodeId, }; pub(crate) trait GenericTrieUpdateSquash<'a, N, V>: GenericTrieUpdate<'a, N, V> @@ -27,7 +27,7 @@ where /// the leaf to the root. /// For range removal, it is called in the end of recursive range removal /// function, which is the definition of post-order traversal. - fn squash_node(&mut self, node_id: GenericUpdatedNodeId) -> Result<(), StorageError> { + fn squash_node(&mut self, node_id: UpdatedNodeId) -> Result<(), StorageError> { let GenericUpdatedTrieNodeWithSize { node, memory_usage } = self.take_node(node_id); match node { GenericUpdatedTrieNode::Empty => { @@ -107,7 +107,7 @@ where fn extend_child( &mut self, // The node being squashed. - node_id: GenericUpdatedNodeId, + node_id: UpdatedNodeId, // The current extension. extension: Box<[u8]>, // The current child. diff --git a/core/store/src/trie/trie_storage_update.rs b/core/store/src/trie/trie_storage_update.rs index 069f5ab1870..758a528df1d 100644 --- a/core/store/src/trie/trie_storage_update.rs +++ b/core/store/src/trie/trie_storage_update.rs @@ -4,8 +4,8 @@ use near_primitives::hash::{hash, CryptoHash}; use near_primitives::state::ValueRef; use super::ops::interface::{ - GenericNodeOrIndex, GenericTrieUpdate, GenericTrieValue, GenericUpdatedNodeId, - GenericUpdatedTrieNode, GenericUpdatedTrieNodeWithSize, + GenericNodeOrIndex, GenericTrieNode, GenericTrieNodeWithSize, GenericTrieUpdate, + GenericTrieValue, GenericUpdatedTrieNode, GenericUpdatedTrieNodeWithSize, UpdatedNodeId, }; use super::{ Children, RawTrieNode, RawTrieNodeWithSize, StorageHandle, StorageValueHandle, Trie, @@ -16,12 +16,11 @@ const INVALID_STORAGE_HANDLE: &str = "invalid storage handle"; pub(crate) type TrieStorageNodePtr = CryptoHash; -pub(crate) type UpdatedTrieStorageNode = GenericUpdatedTrieNode; +pub(crate) type TrieStorageNode = GenericTrieNode; -impl UpdatedTrieStorageNode { +impl TrieStorageNode { fn new_branch(children: Children, value: Option) -> Self { - let children = - Box::new(children.0.map(|child| child.map(|id| GenericNodeOrIndex::Old(id)))); + let children = Box::new(children.0); let value = value.map(ValueHandle::HashAndSize); Self::Branch { children, value } } @@ -30,28 +29,29 @@ impl UpdatedTrieStorageNode { pub fn from_raw_trie_node(node: RawTrieNode) -> Self { match node { RawTrieNode::Leaf(extension, value) => Self::Leaf { - extension: extension.to_vec().into_boxed_slice(), + extension: extension.into_boxed_slice(), value: ValueHandle::HashAndSize(value), }, RawTrieNode::BranchNoValue(children) => Self::new_branch(children, None), RawTrieNode::BranchWithValue(value, children) => { Self::new_branch(children, Some(value)) } - RawTrieNode::Extension(extension, child) => Self::Extension { - extension: extension.to_vec().into_boxed_slice(), - child: GenericNodeOrIndex::Old(child), - }, + RawTrieNode::Extension(extension, child) => { + Self::Extension { extension: extension.into_boxed_slice(), child } + } } } } +pub(crate) type TrieStorageNodeWithSize = GenericTrieNodeWithSize; + pub(crate) type UpdatedTrieStorageNodeWithSize = GenericUpdatedTrieNodeWithSize; -impl UpdatedTrieStorageNodeWithSize { +impl TrieStorageNodeWithSize { pub fn from_raw_trie_node_with_size(node: RawTrieNodeWithSize) -> Self { Self { - node: UpdatedTrieStorageNode::from_raw_trie_node(node.node), + node: TrieStorageNode::from_raw_trie_node(node.node), memory_usage: node.memory_usage, } } @@ -93,7 +93,7 @@ impl<'a> GenericTrieUpdate<'a, TrieStorageNodePtr, ValueHandle> for TrieStorageU fn ensure_updated( &mut self, node: GenericNodeOrIndex, - ) -> Result { + ) -> Result { match node { GenericNodeOrIndex::Old(node_hash) => { self.trie.move_node_to_mutable(self, &node_hash).map(|handle| handle.0) @@ -102,7 +102,7 @@ impl<'a> GenericTrieUpdate<'a, TrieStorageNodePtr, ValueHandle> for TrieStorageU } } - fn take_node(&mut self, index: GenericUpdatedNodeId) -> UpdatedTrieStorageNodeWithSize { + fn take_node(&mut self, index: UpdatedNodeId) -> UpdatedTrieStorageNodeWithSize { self.nodes .get_mut(index) .expect(INVALID_STORAGE_HANDLE) @@ -110,18 +110,18 @@ impl<'a> GenericTrieUpdate<'a, TrieStorageNodePtr, ValueHandle> for TrieStorageU .expect(INVALID_STORAGE_HANDLE) } - fn place_node_at(&mut self, index: GenericUpdatedNodeId, node: UpdatedTrieStorageNodeWithSize) { + fn place_node_at(&mut self, index: UpdatedNodeId, node: UpdatedTrieStorageNodeWithSize) { debug_assert!(self.nodes.get(index).expect(INVALID_STORAGE_HANDLE).is_none()); self.nodes[index] = Some(node); } - fn place_node(&mut self, node: UpdatedTrieStorageNodeWithSize) -> GenericUpdatedNodeId { + fn place_node(&mut self, node: UpdatedTrieStorageNodeWithSize) -> UpdatedNodeId { let index = self.nodes.len(); self.nodes.push(Some(node)); index } - fn get_node_ref(&self, index: GenericUpdatedNodeId) -> &UpdatedTrieStorageNodeWithSize { + fn get_node_ref(&self, index: UpdatedNodeId) -> &UpdatedTrieStorageNodeWithSize { self.nodes.get(index).expect(INVALID_STORAGE_HANDLE).as_ref().expect(INVALID_STORAGE_HANDLE) }