State-db I/o metrics (#4562)

* add usage mod to sp-state-machine

* State usage tracking finalized.

* fix spaces

* add license preamble

* imporove output

* review suggestions

* update naming

* merge fixes

* Update client/db/src/light.rs

Co-Authored-By: Gavin Wood <gavin@parity.io>

Co-authored-by: Gavin Wood <github@gavwood.com>
This commit is contained in:
Nikolay Volf
2020-01-13 11:10:39 +03:00
committed by Gavin Wood
parent 062d6e4425
commit 426c157076
8 changed files with 248 additions and 11 deletions
+22 -2
View File
@@ -28,6 +28,7 @@ use sp_state_machine::{backend::Backend as StateBackend, TrieBackend};
use log::trace;
use sc_client_api::backend::{StorageCollection, ChildStorageCollection};
use std::hash::Hash as StdHash;
use crate::stats::StateUsageStats;
const STATE_CACHE_BLOCKS: usize = 12;
@@ -296,6 +297,8 @@ pub struct CacheChanges<B: BlockT> {
/// in `sync_cache` along with the change overlay.
/// For non-canonical clones local cache and changes are dropped.
pub struct CachingState<S: StateBackend<HasherFor<B>>, B: BlockT> {
/// Usage statistics
usage: StateUsageStats,
/// Backing state.
state: S,
/// Cache data.
@@ -421,6 +424,7 @@ impl<S: StateBackend<HasherFor<B>>, B: BlockT> CachingState<S, B> {
/// Create a new instance wrapping generic State and shared cache.
pub fn new(state: S, shared_cache: SharedCache<B>, parent_hash: Option<B::Hash>) -> Self {
CachingState {
usage: StateUsageStats::new(),
state,
cache: CacheChanges {
shared_cache,
@@ -495,18 +499,22 @@ impl<S: StateBackend<HasherFor<B>>, B: BlockT> StateBackend<HasherFor<B>> for Ca
// Note that local cache makes that lru is not refreshed
if let Some(entry) = local_cache.storage.get(key).cloned() {
trace!("Found in local cache: {:?}", HexDisplay::from(&key));
self.usage.tally_key_read(key, entry.as_ref(), true);
return Ok(entry)
}
let mut cache = self.cache.shared_cache.lock();
if Self::is_allowed(Some(key), None, &self.cache.parent_hash, &cache.modifications) {
if let Some(entry) = cache.lru_storage.get(key).map(|a| a.clone()) {
trace!("Found in shared cache: {:?}", HexDisplay::from(&key));
self.usage.tally_key_read(key, entry.as_ref(), true);
return Ok(entry)
}
}
trace!("Cache miss: {:?}", HexDisplay::from(&key));
let value = self.state.storage(key)?;
RwLockUpgradableReadGuard::upgrade(local_cache).storage.insert(key.to_vec(), value.clone());
self.usage.tally_key_read(key, value.as_ref(), false);
Ok(value)
}
@@ -539,17 +547,25 @@ impl<S: StateBackend<HasherFor<B>>, B: BlockT> StateBackend<HasherFor<B>> for Ca
let local_cache = self.cache.local_cache.upgradable_read();
if let Some(entry) = local_cache.child_storage.get(&key).cloned() {
trace!("Found in local cache: {:?}", key);
return Ok(entry)
return Ok(
self.usage.tally_child_key_read(&key, entry, true)
)
}
let mut cache = self.cache.shared_cache.lock();
if Self::is_allowed(None, Some(&key), &self.cache.parent_hash, &cache.modifications) {
if let Some(entry) = cache.lru_child_storage.get(&key).map(|a| a.clone()) {
trace!("Found in shared cache: {:?}", key);
return Ok(entry)
return Ok(
self.usage.tally_child_key_read(&key, entry, true)
)
}
}
trace!("Cache miss: {:?}", key);
let value = self.state.child_storage(storage_key, child_info, &key.1[..])?;
// just pass it through the usage counter
let value = self.usage.tally_child_key_read(&key, value, false);
RwLockUpgradableReadGuard::upgrade(local_cache).child_storage.insert(key, value.clone());
Ok(value)
}
@@ -646,6 +662,10 @@ impl<S: StateBackend<HasherFor<B>>, B: BlockT> StateBackend<HasherFor<B>> for Ca
fn as_trie_backend(&mut self) -> Option<&TrieBackend<Self::TrieBackendStorage, HasherFor<B>>> {
self.state.as_trie_backend()
}
fn usage_info(&self) -> sp_state_machine::UsageInfo {
self.usage.take()
}
}
#[cfg(test)]