From 5395f13528ae96fed018abbfbd71be5b1ff16ed0 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 26 Aug 2017 19:09:32 +0200 Subject: [PATCH] optimized hashdb keys --- util/src/journaldb/archivedb.rs | 26 +++++++++++++--------- util/src/journaldb/earlymergedb.rs | 26 +++++++++++++--------- util/src/journaldb/overlayrecentdb.rs | 26 +++++++++++++--------- util/src/journaldb/refcounteddb.rs | 2 +- util/src/memorydb.rs | 10 ++++----- util/src/overlaydb.rs | 31 ++++++++++++++++++--------- 6 files changed, 75 insertions(+), 46 deletions(-) diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index fc893654a..68747712d 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -17,6 +17,7 @@ //! Disk-backed `HashDB` implementation. use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::sync::Arc; use rlp::*; use hashdb::*; @@ -66,23 +67,28 @@ impl ArchiveDB { impl HashDB for ArchiveDB { fn keys(&self) -> HashMap { - let mut ret: HashMap = HashMap::new(); - for (key, _) in self.backing.iter(self.column) { - let h = H256::from_slice(&*key); - ret.insert(h, 1); - } + let mut ret: HashMap = self.backing.iter(self.column) + .map(|(key, _)| (H256::from_slice(&*key), 1)) + .collect(); for (key, refs) in self.overlay.keys() { - let refs = *ret.get(&key).unwrap_or(&0) + refs; - ret.insert(key, refs); + match ret.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() += refs; + }, + Entry::Vacant(entry) => { + *entry.insert(refs); + } + } } ret } fn get(&self, key: &H256) -> Option { - let k = self.overlay.raw(key); - if let Some((d, rc)) = k { - if rc > 0 { return Some(d); } + if let Some((d, rc)) = self.overlay.raw(key) { + if rc > 0 { + return Some(d); + } } self.payload(key) } diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index b7b57d537..345005018 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -18,6 +18,7 @@ use std::fmt; use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::sync::Arc; use parking_lot::RwLock; use heapsize::HeapSizeOf; @@ -311,23 +312,28 @@ impl EarlyMergeDB { impl HashDB for EarlyMergeDB { fn keys(&self) -> HashMap { - let mut ret: HashMap = HashMap::new(); - for (key, _) in self.backing.iter(self.column) { - let h = H256::from_slice(&*key); - ret.insert(h, 1); - } + let mut ret: HashMap = self.backing.iter(self.column) + .map(|(key, _)| (H256::from_slice(&*key), 1)) + .collect(); for (key, refs) in self.overlay.keys() { - let refs = *ret.get(&key).unwrap_or(&0) + refs; - ret.insert(key, refs); + match ret.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() += refs; + }, + Entry::Vacant(entry) => { + *entry.insert(refs); + } + } } ret } fn get(&self, key: &H256) -> Option { - let k = self.overlay.raw(key); - if let Some((d, rc)) = k { - if rc > 0 { return Some(d) } + if let Some((d, rc)) = self.overlay.raw(key) { + if rc > 0 { + return Some(d) + } } self.payload(key) } diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index e96430e06..4b9efadc7 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -17,6 +17,7 @@ //! `JournalDB` over in-memory overlay use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::sync::Arc; use parking_lot::RwLock; use heapsize::HeapSizeOf; @@ -407,23 +408,28 @@ impl JournalDB for OverlayRecentDB { impl HashDB for OverlayRecentDB { fn keys(&self) -> HashMap { - let mut ret: HashMap = HashMap::new(); - for (key, _) in self.backing.iter(self.column) { - let h = H256::from_slice(&*key); - ret.insert(h, 1); - } + let mut ret: HashMap = self.backing.iter(self.column) + .map(|(key, _)| (H256::from_slice(&*key), 1)) + .collect(); for (key, refs) in self.transaction_overlay.keys() { - let refs = *ret.get(&key).unwrap_or(&0) + refs; - ret.insert(key, refs); + match ret.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() += refs; + }, + Entry::Vacant(entry) => { + *entry.insert(refs); + } + } } ret } fn get(&self, key: &H256) -> Option { - let k = self.transaction_overlay.raw(key); - if let Some((d, rc)) = k { - if rc > 0 { return Some(d) } + if let Some((d, rc)) = self.transaction_overlay.raw(key) { + if rc > 0 { + return Some(d) + } } let v = { let journal_overlay = self.journal_overlay.read(); diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs index e38994700..1b9c9ded8 100644 --- a/util/src/journaldb/refcounteddb.rs +++ b/util/src/journaldb/refcounteddb.rs @@ -198,7 +198,7 @@ impl JournalDB for RefCountedDB { fn consolidate(&mut self, mut with: MemoryDB) { for (key, (value, rc)) in with.drain() { for _ in 0..rc { - self.emplace(key.clone(), value.clone()); + self.emplace(key, value.clone()); } for _ in rc..0 { diff --git a/util/src/memorydb.rs b/util/src/memorydb.rs index fcfde9695..14d3cb639 100644 --- a/util/src/memorydb.rs +++ b/util/src/memorydb.rs @@ -16,14 +16,14 @@ //! Reference-counted memory-based `HashDB` implementation. -use hash::*; -use rlp::*; -use sha3::*; -use hashdb::*; -use heapsize::*; use std::mem; use std::collections::HashMap; use std::collections::hash_map::Entry; +use heapsize::HeapSizeOf; +use hash::{H256FastMap, H256}; +use rlp::NULL_RLP; +use sha3::*; +use hashdb::*; /// Reference-counted memory-based `HashDB` implementation. /// diff --git a/util/src/overlaydb.rs b/util/src/overlaydb.rs index 6b6f501a7..dbd22c59d 100644 --- a/util/src/overlaydb.rs +++ b/util/src/overlaydb.rs @@ -16,13 +16,14 @@ //! Disk-backed `HashDB` implementation. +use std::sync::Arc; +use std::collections::HashMap; +use std::collections::hash_map::Entry; use error::*; use hash::*; use rlp::*; use hashdb::*; use memorydb::*; -use std::sync::*; -use std::collections::HashMap; use kvdb::{KeyValueDB, DBTransaction}; /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay. @@ -125,19 +126,27 @@ impl OverlayDB { impl HashDB for OverlayDB { fn keys(&self) -> HashMap { - let mut ret: HashMap = HashMap::new(); - for (key, _) in self.backing.iter(self.column) { - let h = H256::from_slice(&*key); - let r = self.payload(&h).unwrap().1; - ret.insert(h, r as i32); - } + let mut ret: HashMap = self.backing.iter(self.column) + .map(|(key, _)| { + let h = H256::from_slice(&*key); + let r = self.payload(&h).unwrap().1; + (h, r as i32) + }) + .collect(); for (key, refs) in self.overlay.keys() { - let refs = *ret.get(&key).unwrap_or(&0) + refs; - ret.insert(key, refs); + match ret.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() += refs; + }, + Entry::Vacant(entry) => { + *entry.insert(refs); + } + } } ret } + fn get(&self, key: &H256) -> Option { // return ok if positive; if negative, check backing - might be enough references there to make // it positive again. @@ -165,6 +174,7 @@ impl HashDB for OverlayDB { _ => None, } } + fn contains(&self, key: &H256) -> bool { // return ok if positive; if negative, check backing - might be enough references there to make // it positive again. @@ -185,6 +195,7 @@ impl HashDB for OverlayDB { } } } + fn insert(&mut self, value: &[u8]) -> H256 { self.overlay.insert(value) } fn emplace(&mut self, key: H256, value: DBValue) { self.overlay.emplace(key, value); } fn remove(&mut self, key: &H256) { self.overlay.remove(key); }