From 167a129d59571151897f8b750cc85423a99748a1 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 6 Sep 2022 13:25:48 +0200 Subject: [PATCH] =?UTF-8?q?store:=20make=20TrieNode=E2=80=99s=20debug=20fo?= =?UTF-8?q?rmatting=20more=20concise=20(#7557)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default Debug derive for types is quite verbose with a lot of vertical spacing. For example, TrieNode branches are printed as a list with each empty branch as a None on its own line. This isn’t very ergonomic when trying to debug trie nodes and printing a lot of the nodes to output. Replace the default Debug implementation for TrieNode, NodeHandle and ValueHandle by custom ones which are more concise and don’t waste space on empty nodes. --- core/store/src/trie/mod.rs | 58 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/core/store/src/trie/mod.rs b/core/store/src/trie/mod.rs index b09282ac80e..dfdfec7593d 100644 --- a/core/store/src/trie/mod.rs +++ b/core/store/src/trie/mod.rs @@ -60,7 +60,7 @@ pub struct TrieCosts { const TRIE_COSTS: TrieCosts = TrieCosts { byte_of_key: 2, byte_of_value: 1, node_cost: 50 }; -#[derive(Clone, Hash, Debug)] +#[derive(Clone, Hash)] enum NodeHandle { InMemory(StorageHandle), Hash(CryptoHash), @@ -75,13 +75,31 @@ impl NodeHandle { } } -#[derive(Clone, Hash, Debug)] +impl std::fmt::Debug for NodeHandle { + fn fmt(&self, fmtr: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Hash(hash) => write!(fmtr, "{hash}"), + Self::InMemory(handle) => write!(fmtr, "@{}", handle.0), + } + } +} + +#[derive(Clone, Hash)] enum ValueHandle { InMemory(StorageValueHandle), HashAndSize(u32, CryptoHash), } -#[derive(Clone, Hash, Debug)] +impl std::fmt::Debug for ValueHandle { + fn fmt(&self, fmtr: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::HashAndSize(size, hash) => write!(fmtr, "{hash}, size:{size}"), + Self::InMemory(handle) => write!(fmtr, "@{}", handle.0), + } + } +} + +#[derive(Clone, Hash)] enum TrieNode { /// Null trie node. Could be an empty root or an empty branch entry. Empty, @@ -255,6 +273,40 @@ impl TrieNode { } } +impl std::fmt::Debug for TrieNode { + /// Formats single trie node. + /// + /// Width can be used to specify indentation. + fn fmt(&self, fmtr: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let empty = ""; + let indent = fmtr.width().unwrap_or(0); + match self { + TrieNode::Empty => write!(fmtr, "{empty:indent$}Empty"), + TrieNode::Leaf(key, value) => write!( + fmtr, + "{empty:indent$}Leaf({:?}, {value:?})", + NibbleSlice::from_encoded(key).0 + ), + TrieNode::Branch(children, value) => { + match value { + Some(value) => write!(fmtr, "{empty:indent$}Branch({value:?}):"), + None => write!(fmtr, "{empty:indent$}Branch:"), + }?; + for (idx, child) in children.iter().enumerate() { + if let Some(child) = child { + write!(fmtr, "\n{empty:indent$} {idx:x}: {child:?}")?; + } + } + Ok(()) + } + TrieNode::Extension(key, child) => { + let key = NibbleSlice::from_encoded(key).0; + write!(fmtr, "{empty:indent$}Extension({key:?}, {child:?})") + } + } + } +} + #[derive(Debug, Eq, PartialEq)] #[allow(clippy::large_enum_variant)] enum RawTrieNode {