aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2021-11-04 10:11:15 +0100
committerAlex Auvolat <alex@adnab.me>2021-11-04 10:11:58 +0100
commit927a369036a6c54fb4116274c229d7647a038be4 (patch)
tree842d6fed82d7138be4a482badf0568a38222b580
parentda95f014a22485d97085a5890689ae4f54c11cb5 (diff)
downloadsledcli-927a369036a6c54fb4116274c229d7647a038be4.tar.gz
sledcli-927a369036a6c54fb4116274c229d7647a038be4.zip
add ll and lu commands to show table sizes
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--rustfmt.toml1
-rw-r--r--src/main.rs85
4 files changed, 72 insertions, 22 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f7aa5a7..e6785fb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -196,6 +196,12 @@ dependencies = [
]
[[package]]
+name = "humansize"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026"
+
+[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -425,6 +431,7 @@ version = "0.0.1"
dependencies = [
"anyhow",
"hexdump",
+ "humansize",
"rustyline",
"sled",
"structopt",
diff --git a/Cargo.toml b/Cargo.toml
index 9edf0a5..a8717dc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,3 +14,4 @@ structopt = { version = "0.3", default-features = false }
hexdump = "0.1"
utf-8 = "0.7"
anyhow = "1.0"
+humansize = "1.1"
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 0000000..218e203
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1 @@
+hard_tabs = true
diff --git a/src/main.rs b/src/main.rs
index a2de0e1..51f8f06 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,10 @@
-use std::path::PathBuf;
use std::ops::Deref;
+use std::path::PathBuf;
use anyhow::Result;
+use humansize::{file_size_opts, FileSize};
+
use rustyline::error::ReadlineError;
use rustyline::Editor;
@@ -14,7 +16,7 @@ use sled::IVec;
#[structopt(name = "sledcli")]
struct Opt {
/// Path to Sled database
- #[structopt(name="path")]
+ #[structopt(name = "path")]
path: PathBuf,
}
@@ -45,38 +47,45 @@ fn main() {
};
let mut readline = Editor::<()>::new();
- loop {
- let lineread = readline.readline(&format!("{}> ", try_string(&state.tree.name())));
- match lineread {
- Ok(line) => {
- readline.add_history_entry(line.as_str());
+ loop {
+ let prefix = match state.displaymode {
+ DisplayMode::HexDump => "hex",
+ DisplayMode::TryString => "str",
+ DisplayMode::Mixed => "mix",
+ };
+ let prompt = format!("[{}] {}> ", prefix, try_string(&state.tree.name()));
+ let lineread = readline.readline(&prompt);
+ match lineread {
+ Ok(line) => {
+ readline.add_history_entry(line.as_str());
if let Err(e) = do_command(&line, &mut state) {
println!("Error: {}", e);
}
- },
- Err(ReadlineError::Interrupted) => {
+ }
+ Err(ReadlineError::Interrupted) => {
println!("^C");
continue;
- },
- Err(ReadlineError::Eof) => {
- break
- },
- Err(err) => {
- println!("Readline error: {:?}", err);
- break
- }
- }
- }
+ }
+ Err(ReadlineError::Eof) => break,
+ Err(err) => {
+ println!("Readline error: {:?}", err);
+ break;
+ }
+ }
+ }
}
fn try_string(input: &sled::IVec) -> String {
- let mut string = String::new();
+ let mut string = String::new();
utf8::LossyDecoder::new(|s| string.push_str(s)).feed(input);
string
}
fn do_command(line: &str, state: &mut State) -> Result<()> {
- let parts = line.split(' ').filter(|part| part.len() > 0).collect::<Vec<_>>();
+ let parts = line
+ .split(' ')
+ .filter(|part| part.len() > 0)
+ .collect::<Vec<_>>();
if parts.is_empty() {
return Ok(());
}
@@ -89,8 +98,40 @@ fn do_command(line: &str, state: &mut State) -> Result<()> {
println!("{}", try_string(&name));
}
}
+ ["ll"] => {
+ let mut names = state.db.tree_names();
+ names.sort();
+ for name in names {
+ let nent = state.db.open_tree(&name)?.len();
+ println!("{:8} {}", nent, try_string(&name));
+ }
+ }
+ ["lu"] => {
+ let mut names = state.db.tree_names();
+ names.sort();
+ for name in names {
+ let tree = state.db.open_tree(&name)?;
+ let nent = tree.len();
+ let mut size = 0;
+ for ent in tree.iter() {
+ let (k, v) = ent?;
+ size += k.len() + v.len();
+ }
+ println!(
+ "{:8} {:>12} {}",
+ nent,
+ size.file_size(file_size_opts::CONVENTIONAL).unwrap(),
+ try_string(&name)
+ );
+ }
+ }
["cd", treename] => {
- if state.db.tree_names().iter().any(|t| t == treename.as_bytes()) {
+ if state
+ .db
+ .tree_names()
+ .iter()
+ .any(|t| t == treename.as_bytes())
+ {
state.tree = state.db.open_tree(treename.as_bytes())?;
} else {
println!("Tree {} does not exist", treename);