diff --git a/firewood/src/merkle.rs b/firewood/src/merkle.rs index 3f91653da..e42f2594f 100644 --- a/firewood/src/merkle.rs +++ b/firewood/src/merkle.rs @@ -76,7 +76,12 @@ macro_rules! write_attributes { write!($writer, " val={}", string)? } _ => { - write!($writer, " val={}", hex::encode($value))?; + let hex = hex::encode($value); + if hex.len() > 6 { + write!($writer, " val={:.6}...", hex)?; + } else { + write!($writer, " val={}", hex)?; + } } } } @@ -341,7 +346,10 @@ impl Merkle { seen: &mut HashSet, writer: &mut dyn Write, ) -> Result<(), MerkleError> { - write!(writer, " {addr}[label=\"addr:{addr:?} hash:{hash:?}")?; + write!(writer, " {addr}[label=\"addr:{addr:?}")?; + if let Some(hash) = hash { + write!(writer, " hash:{hash:.6?}...")?; + } match &*self.read_node(addr)? { Node::Branch(b) => { @@ -378,7 +386,7 @@ impl Merkle { pub fn dump(&self) -> Result { let mut result = vec![]; - writeln!(result, "digraph Merkle {{")?; + writeln!(result, "digraph Merkle {{\n rankdir=LR;")?; if let Some((root_addr, root_hash)) = self.nodestore.root_address_and_hash()? { writeln!(result, " root -> {root_addr}")?; let mut seen = HashSet::new(); diff --git a/fwdctl/src/graph.rs b/fwdctl/src/graph.rs new file mode 100644 index 000000000..833c1e140 --- /dev/null +++ b/fwdctl/src/graph.rs @@ -0,0 +1,27 @@ +// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE.md for licensing terms. + +use clap::Args; +use firewood::db::{Db, DbConfig}; +use firewood::v2::api; +use std::io::stdout; + +#[derive(Debug, Args)] +pub struct Options { + /// The database path (if no path is provided, return an error). Defaults to firewood. + #[arg( + value_name = "DB_NAME", + default_value_t = String::from("firewood"), + help = "Name of the database" + )] + pub db: String, +} + +pub(super) async fn run(opts: &Options) -> Result<(), api::Error> { + log::debug!("dump database {:?}", opts); + let cfg = DbConfig::builder().truncate(false); + + let db = Db::new(opts.db.clone(), cfg.build()).await?; + db.dump(&mut stdout())?; + Ok(()) +} diff --git a/fwdctl/src/main.rs b/fwdctl/src/main.rs index fca9d6d87..1c80537e7 100644 --- a/fwdctl/src/main.rs +++ b/fwdctl/src/main.rs @@ -8,6 +8,7 @@ pub mod create; pub mod delete; pub mod dump; pub mod get; +pub mod graph; pub mod insert; pub mod root; @@ -44,6 +45,8 @@ enum Commands { Root(root::Options), /// Dump contents of key/value store Dump(dump::Options), + /// Produce a dot file of the database + Graph(graph::Options), } #[tokio::main] @@ -62,5 +65,6 @@ async fn main() -> Result<(), api::Error> { Commands::Delete(opts) => delete::run(opts).await, Commands::Root(opts) => root::run(opts).await, Commands::Dump(opts) => dump::run(opts).await, + Commands::Graph(opts) => graph::run(opts).await, } } diff --git a/storage/src/nodestore.rs b/storage/src/nodestore.rs index 3d8040e03..44d51db81 100644 --- a/storage/src/nodestore.rs +++ b/storage/src/nodestore.rs @@ -424,7 +424,7 @@ impl NodeStore, S> { return Ok(Some((address, index as AreaIndex))); } - trace!("No free blocks of sufficient size {index} found"); + trace!("No free blocks of sufficient size {index_wanted} found"); counter!("firewood.space.notfree").increment(AREA_SIZES[index_wanted as usize]); Ok(None) } diff --git a/storage/src/trie_hash.rs b/storage/src/trie_hash.rs index 35f403ccd..89df4b061 100644 --- a/storage/src/trie_hash.rs +++ b/storage/src/trie_hash.rs @@ -32,7 +32,8 @@ impl AsRef<[u8]> for TrieHash { impl Debug for TrieHash { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - write!(f, "{}", hex::encode(self.0)) + let width = f.precision().unwrap_or_default(); + write!(f, "{:.*}", width, hex::encode(self.0)) } }