diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/db/Cargo.toml | 7 | ||||
-rw-r--r-- | src/db/lib.rs | 52 | ||||
-rw-r--r-- | src/db/sled_adapter.rs | 9 | ||||
-rw-r--r-- | src/garage/repair/online.rs | 15 |
4 files changed, 73 insertions, 10 deletions
diff --git a/src/db/Cargo.toml b/src/db/Cargo.toml index 82cf49dc..a0034169 100644 --- a/src/db/Cargo.toml +++ b/src/db/Cargo.toml @@ -18,6 +18,7 @@ required-features = ["cli"] [dependencies] err-derive = "0.3" +hex = "0.4" hexdump = "0.1" tracing = "0.1.30" @@ -25,6 +26,11 @@ heed = { version = "0.11", default-features = false, features = ["lmdb"], option rusqlite = { version = "0.27", optional = true } sled = { version = "0.34", optional = true } +rmp-serde = { version = "0.15", optional = true } +serde = { version = "1.0", default-features = false, features = ["derive", "rc"], optional = true } +serde-transcode = { version = "1.1", optional = true } +nettext = { version = "0.3.2", default-features = false, features = ["serde"], optional = true, path = "../../../nettext" } + # cli deps clap = { version = "3.1.18", optional = true, features = ["derive", "env"] } pretty_env_logger = { version = "0.4", optional = true } @@ -38,3 +44,4 @@ bundled-libs = [ "rusqlite/bundled" ] cli = ["clap", "pretty_env_logger"] lmdb = [ "heed" ] sqlite = [ "rusqlite" ] +debuglog = [ "serde", "rmp-serde", "nettext", "serde-transcode" ] diff --git a/src/db/lib.rs b/src/db/lib.rs index 11cae4e3..cd2774fa 100644 --- a/src/db/lib.rs +++ b/src/db/lib.rs @@ -174,8 +174,21 @@ impl Tree { } #[inline] + pub fn name(&self) -> Option<String> { + self.0.tree_name(self.1) + } + + #[inline] pub fn get<T: AsRef<[u8]>>(&self, key: T) -> Result<Option<Value>> { - self.0.get(self.1, key.as_ref()) + let res = self.0.get(self.1, key.as_ref())?; + #[cfg(feature = "debuglog")] + debuglog( + self.name(), + "GET", + key.as_ref(), + res.as_deref().unwrap_or(b"-"), + ); + Ok(res) } #[inline] pub fn len(&self) -> Result<usize> { @@ -204,7 +217,10 @@ impl Tree { key: T, value: U, ) -> Result<Option<Value>> { - self.0.insert(self.1, key.as_ref(), value.as_ref()) + let res = self.0.insert(self.1, key.as_ref(), value.as_ref())?; + #[cfg(feature = "debuglog")] + debuglog(self.name(), "PUT", key.as_ref(), value.as_ref()); + Ok(res) } /// Returns the old value if there was one #[inline] @@ -267,7 +283,10 @@ impl<'a> Transaction<'a> { key: T, value: U, ) -> TxOpResult<Option<Value>> { - self.0.insert(tree.1, key.as_ref(), value.as_ref()) + let res = self.0.insert(tree.1, key.as_ref(), value.as_ref())?; + #[cfg(feature = "debuglog")] + debuglog(tree.name(), "txPUT", key.as_ref(), value.as_ref()); + Ok(res) } /// Returns the old value if there was one #[inline] @@ -324,6 +343,7 @@ pub(crate) trait IDb: Send + Sync { fn engine(&self) -> String; fn open_tree(&self, name: &str) -> Result<usize>; fn list_trees(&self) -> Result<Vec<String>>; + fn tree_name(&self, tree: usize) -> Option<String>; fn get(&self, tree: usize, key: &[u8]) -> Result<Option<Value>>; fn len(&self, tree: usize) -> Result<usize>; @@ -421,3 +441,29 @@ fn get_bound<K: AsRef<[u8]>>(b: Bound<&K>) -> Bound<&[u8]> { Bound::Unbounded => Bound::Unbounded, } } + +#[cfg(feature = "debuglog")] +fn debuglog(tree: Option<String>, action: &str, k: &[u8], v: &[u8]) { + let key = String::from_utf8(nettext::switch64::encode(k, false)).unwrap(); + let tree = tree.as_deref().unwrap_or("(?)"); + if let Ok(vstr) = std::str::from_utf8(v) { + eprintln!("{} {} {} S:{}", tree, action, key, vstr); + } else { + let mut vread = &v[..]; + let mut vder = rmp_serde::decode::Deserializer::new(&mut vread); + let mut vser = nettext::serde::Serializer { + string_format: nettext::BytesEncoding::Switch64 { + allow_whitespace: true, + }, + bytes_format: nettext::BytesEncoding::Hex { split: true }, + }; + if let Some(venc) = serde_transcode::transcode(&mut vder, &mut vser) + .ok() + .and_then(|x| String::from_utf8(x.encode_concise()).ok()) + { + eprintln!("{} {} {} N:{}", tree, action, key, venc); + } else { + eprintln!("{} {} {} X:{}", tree, action, key, hex::encode(v)); + } + } +} diff --git a/src/db/sled_adapter.rs b/src/db/sled_adapter.rs index cf61867d..31a4889f 100644 --- a/src/db/sled_adapter.rs +++ b/src/db/sled_adapter.rs @@ -88,6 +88,15 @@ impl IDb for SledDb { Ok(trees) } + fn tree_name(&self, tree: usize) -> Option<String> { + self.trees + .read() + .unwrap() + .0 + .get(tree) + .and_then(|x| String::from_utf8(x.name().to_vec()).ok()) + } + // ---- fn get(&self, tree: usize, key: &[u8]) -> Result<Option<Value>> { diff --git a/src/garage/repair/online.rs b/src/garage/repair/online.rs index 6e8ec2d3..7120972c 100644 --- a/src/garage/repair/online.rs +++ b/src/garage/repair/online.rs @@ -171,13 +171,14 @@ impl Worker for RepairBlockrefsWorker { } async fn work(&mut self, _must_exit: &mut watch::Receiver<bool>) -> Result<WorkerState, Error> { - let (item_bytes, next_pos) = match self.garage.block_ref_table.data.store.get_gt(&self.pos)? { - Some((k, v)) => (v, k), - None => { - info!("repair_block_ref: finished, done {}", self.counter); - return Ok(WorkerState::Done); - } - }; + let (item_bytes, next_pos) = + match self.garage.block_ref_table.data.store.get_gt(&self.pos)? { + Some((k, v)) => (v, k), + None => { + info!("repair_block_ref: finished, done {}", self.counter); + return Ok(WorkerState::Done); + } + }; let block_ref = rmp_serde::decode::from_read_ref::<_, BlockRef>(&item_bytes)?; if !block_ref.deleted.get() { |