diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs
index 2d666d139..cb09432dc 100644
--- a/kvdb-rocksdb/src/lib.rs
+++ b/kvdb-rocksdb/src/lib.rs
@@ -15,6 +15,7 @@
// along with Parity. If not, see .
mod iter;
+mod stats;
use std::{cmp, collections::HashMap, convert::identity, error, fs, io, mem, path::Path, result};
@@ -271,6 +272,8 @@ pub struct Database {
block_opts: BlockBasedOptions,
// Dirty values added with `write_buffered`. Cleaned on `flush`.
overlay: RwLock>>,
+ #[ignore_malloc_size_of = "insignificant"]
+ stats: stats::RunningDbStats,
// Values currently being flushed. Cleared when `flush` completes.
flushing: RwLock>>,
// Prevents concurrent flushes.
@@ -403,6 +406,7 @@ impl Database {
read_opts,
write_opts,
block_opts,
+ stats: stats::RunningDbStats::new(),
})
}
@@ -428,20 +432,32 @@ impl Database {
match *self.db.read() {
Some(ref cfs) => {
let mut batch = WriteBatch::default();
+ let mut ops: usize = 0;
+ let mut bytes: usize = 0;
mem::swap(&mut *self.overlay.write(), &mut *self.flushing.write());
{
for (c, column) in self.flushing.read().iter().enumerate() {
+ ops += column.len();
for (key, state) in column.iter() {
let cf = cfs.cf(c);
match *state {
- KeyState::Delete => batch.delete_cf(cf, key).map_err(other_io_err)?,
- KeyState::Insert(ref value) => batch.put_cf(cf, key, value).map_err(other_io_err)?,
+ KeyState::Delete => {
+ bytes += key.len();
+ batch.delete_cf(cf, key).map_err(other_io_err)?
+ }
+ KeyState::Insert(ref value) => {
+ bytes += key.len() + value.len();
+ batch.put_cf(cf, key, value).map_err(other_io_err)?
+ }
};
}
}
}
check_for_corruption(&self.path, cfs.db.write_opt(batch, &self.write_opts))?;
+ self.stats.tally_transactions(1);
+ self.stats.tally_writes(ops as u64);
+ self.stats.tally_bytes_written(bytes as u64);
for column in self.flushing.write().iter_mut() {
column.clear();
@@ -474,6 +490,12 @@ impl Database {
Some(ref cfs) => {
let mut batch = WriteBatch::default();
let ops = tr.ops;
+
+ self.stats.tally_writes(ops.len() as u64);
+ self.stats.tally_transactions(1);
+
+ let mut stats_total_bytes = 0;
+
for op in ops {
// remove any buffered operation for this key
self.overlay.write()[op.col() as usize].remove(op.key());
@@ -481,10 +503,18 @@ impl Database {
let cf = cfs.cf(op.col() as usize);
match op {
- DBOp::Insert { col: _, key, value } => batch.put_cf(cf, &key, &value).map_err(other_io_err)?,
- DBOp::Delete { col: _, key } => batch.delete_cf(cf, &key).map_err(other_io_err)?,
+ DBOp::Insert { col: _, key, value } => {
+ stats_total_bytes += key.len() + value.len();
+ batch.put_cf(cf, &key, &value).map_err(other_io_err)?
+ }
+ DBOp::Delete { col: _, key } => {
+ // We count deletes as writes.
+ stats_total_bytes += key.len();
+ batch.delete_cf(cf, &key).map_err(other_io_err)?
+ }
};
}
+ self.stats.tally_bytes_written(stats_total_bytes as u64);
check_for_corruption(&self.path, cfs.db.write_opt(batch, &self.write_opts))
}
@@ -496,6 +526,7 @@ impl Database {
pub fn get(&self, col: u32, key: &[u8]) -> io::Result