Caching optimizations (#2505)
This commit is contained in:
parent
533af43313
commit
7756031d06
@ -21,7 +21,7 @@ use util::sha3::*;
|
|||||||
use bit_set::BitSet;
|
use bit_set::BitSet;
|
||||||
use super::super::instructions;
|
use super::super::instructions;
|
||||||
|
|
||||||
const CACHE_CODE_ITEMS: usize = 4096;
|
const CACHE_CODE_ITEMS: usize = 65536;
|
||||||
|
|
||||||
/// GLobal cache for EVM interpreter
|
/// GLobal cache for EVM interpreter
|
||||||
pub struct SharedCache {
|
pub struct SharedCache {
|
||||||
|
@ -47,14 +47,16 @@ pub type ApplyResult = Result<ApplyOutcome, Error>;
|
|||||||
/// Account modification state. Used to check if the account was
|
/// Account modification state. Used to check if the account was
|
||||||
/// Modified in between commits and overall.
|
/// Modified in between commits and overall.
|
||||||
enum AccountState {
|
enum AccountState {
|
||||||
/// Account was never modified in this state object.
|
/// Account was loaded from disk and never modified in this state object.
|
||||||
Clean,
|
CleanFresh,
|
||||||
|
/// Account was loaded from the global cache and never modified.
|
||||||
|
CleanCached,
|
||||||
/// Account has been modified and is not committed to the trie yet.
|
/// Account has been modified and is not committed to the trie yet.
|
||||||
/// This is set than any of the account data is changed, including
|
/// This is set if any of the account data is changed, including
|
||||||
/// storage and code.
|
/// storage and code.
|
||||||
Dirty,
|
Dirty,
|
||||||
/// Account was modified and committed to the trie.
|
/// Account was modified and committed to the trie.
|
||||||
Commited,
|
Committed,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -105,7 +107,15 @@ impl AccountEntry {
|
|||||||
fn new_clean(account: Option<Account>) -> AccountEntry {
|
fn new_clean(account: Option<Account>) -> AccountEntry {
|
||||||
AccountEntry {
|
AccountEntry {
|
||||||
account: account,
|
account: account,
|
||||||
state: AccountState::Clean,
|
state: AccountState::CleanFresh,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new account entry and mark it as clean and cached.
|
||||||
|
fn new_clean_cached(account: Option<Account>) -> AccountEntry {
|
||||||
|
AccountEntry {
|
||||||
|
account: account,
|
||||||
|
state: AccountState::CleanCached,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,7 +518,7 @@ impl State {
|
|||||||
{
|
{
|
||||||
let mut trie = factories.trie.from_existing(db.as_hashdb_mut(), root).unwrap();
|
let mut trie = factories.trie.from_existing(db.as_hashdb_mut(), root).unwrap();
|
||||||
for (address, ref mut a) in accounts.iter_mut().filter(|&(_, ref a)| a.is_dirty()) {
|
for (address, ref mut a) in accounts.iter_mut().filter(|&(_, ref a)| a.is_dirty()) {
|
||||||
a.state = AccountState::Commited;
|
a.state = AccountState::Committed;
|
||||||
match a.account {
|
match a.account {
|
||||||
Some(ref mut account) => {
|
Some(ref mut account) => {
|
||||||
try!(trie.insert(address, &account.rlp()));
|
try!(trie.insert(address, &account.rlp()));
|
||||||
@ -526,7 +536,7 @@ impl State {
|
|||||||
fn commit_cache(&mut self) {
|
fn commit_cache(&mut self) {
|
||||||
let mut addresses = self.cache.borrow_mut();
|
let mut addresses = self.cache.borrow_mut();
|
||||||
trace!("Committing cache {:?} entries", addresses.len());
|
trace!("Committing cache {:?} entries", addresses.len());
|
||||||
for (address, a) in addresses.drain().filter(|&(_, ref a)| !a.is_dirty()) {
|
for (address, a) in addresses.drain().filter(|&(_, ref a)| a.state == AccountState::Committed || a.state == AccountState::CleanFresh) {
|
||||||
self.db.cache_account(address, a.account);
|
self.db.cache_account(address, a.account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -638,10 +648,7 @@ impl State {
|
|||||||
Self::update_account_cache(require, account, accountdb.as_hashdb());
|
Self::update_account_cache(require, account, accountdb.as_hashdb());
|
||||||
}
|
}
|
||||||
let r = f(maybe_acc.as_ref());
|
let r = f(maybe_acc.as_ref());
|
||||||
match maybe_acc {
|
self.insert_cache(a, AccountEntry::new_clean(maybe_acc));
|
||||||
Some(account) => self.insert_cache(a, AccountEntry::new_clean(Some(account))),
|
|
||||||
None => self.insert_cache(a, AccountEntry::new_clean(None)),
|
|
||||||
}
|
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -660,8 +667,7 @@ impl State {
|
|||||||
let contains_key = self.cache.borrow().contains_key(a);
|
let contains_key = self.cache.borrow().contains_key(a);
|
||||||
if !contains_key {
|
if !contains_key {
|
||||||
match self.db.get_cached_account(a) {
|
match self.db.get_cached_account(a) {
|
||||||
Some(Some(acc)) => self.insert_cache(a, AccountEntry::new_clean(Some(acc))),
|
Some(acc) => self.insert_cache(a, AccountEntry::new_clean_cached(acc)),
|
||||||
Some(None) => self.insert_cache(a, AccountEntry::new_clean(None)),
|
|
||||||
None => {
|
None => {
|
||||||
let maybe_acc = if self.db.check_account_bloom(a) {
|
let maybe_acc = if self.db.check_account_bloom(a) {
|
||||||
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
|
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
|
||||||
|
@ -24,7 +24,7 @@ use bloom_journal::{Bloom, BloomJournal};
|
|||||||
use db::COL_ACCOUNT_BLOOM;
|
use db::COL_ACCOUNT_BLOOM;
|
||||||
use byteorder::{LittleEndian, ByteOrder};
|
use byteorder::{LittleEndian, ByteOrder};
|
||||||
|
|
||||||
const STATE_CACHE_ITEMS: usize = 65536;
|
const STATE_CACHE_ITEMS: usize = 256000;
|
||||||
|
|
||||||
pub const ACCOUNT_BLOOM_SPACE: usize = 1048576;
|
pub const ACCOUNT_BLOOM_SPACE: usize = 1048576;
|
||||||
pub const DEFAULT_ACCOUNT_PRESET: usize = 1000000;
|
pub const DEFAULT_ACCOUNT_PRESET: usize = 1000000;
|
||||||
|
Loading…
Reference in New Issue
Block a user