@@ -20,6 +20,7 @@ use crate::triedb::TrieDB;
2020use crate :: { Trie , TrieError , TrieMut } ;
2121use ccrypto:: { blake256, BLAKE_NULL_RLP } ;
2222use cdb:: { DBValue , HashDB } ;
23+ use lru_cache:: LruCache ;
2324use primitives:: H256 ;
2425use std:: fmt;
2526
@@ -31,16 +32,19 @@ pub(crate) struct TrieDBMut<'a> {
3132 db : & ' a mut dyn HashDB ,
3233 // When Trie is empty, root has None.
3334 root : & ' a mut H256 ,
35+ cache : LruCache < H256 , Vec < u8 > > ,
3436}
3537
3638impl < ' a > TrieDBMut < ' a > {
3739 /// Create a new trie with backing database `db` and empty `root`.
3840 pub fn new ( db : & ' a mut dyn HashDB , root : & ' a mut H256 ) -> Self {
3941 * root = BLAKE_NULL_RLP ;
4042
43+ let cache: LruCache < H256 , Vec < u8 > > = LruCache :: new ( 3000 ) ;
4144 TrieDBMut {
4245 db,
4346 root,
47+ cache,
4448 }
4549 }
4650
@@ -51,9 +55,11 @@ impl<'a> TrieDBMut<'a> {
5155 return Err ( TrieError :: InvalidStateRoot ( * root) )
5256 }
5357
58+ let cache: LruCache < H256 , Vec < u8 > > = LruCache :: new ( 3000 ) ;
5459 Ok ( TrieDBMut {
5560 db,
5661 root,
62+ cache,
5763 } )
5864 }
5965
@@ -67,16 +73,27 @@ impl<'a> TrieDBMut<'a> {
6773 ) -> crate :: Result < H256 > {
6874 match cur_node_hash {
6975 Some ( hash) => {
70- let node_rlp = self . db . get ( & hash) . ok_or_else ( || TrieError :: IncompleteDatabase ( hash) ) ?;
71-
72- match RlpNode :: decoded ( & node_rlp) {
76+ // FIXME: Refactoring is required to reduce access to the cache.
77+ // the current code queries the cache twice when the data is cached.
78+ let node_rlp;
79+ let decoded_rlp = if self . cache . contains_key ( & hash) {
80+ node_rlp = self . cache . get_mut ( & hash) . unwrap ( ) . to_vec ( ) ;
81+ RlpNode :: decoded ( & node_rlp)
82+ } else {
83+ node_rlp = self . db . get ( & hash) . ok_or_else ( || TrieError :: IncompleteDatabase ( hash) ) ?;
84+ self . cache . insert ( hash, ( & * node_rlp) . to_vec ( ) ) ;
85+ RlpNode :: decoded ( & node_rlp)
86+ } ;
87+
88+ match decoded_rlp {
7389 Some ( RlpNode :: Leaf ( partial, value) ) => {
7490 // Renew the Leaf
7591 if partial == path {
7692 let node = RlpNode :: Leaf ( path, insert_value) ;
7793 let node_rlp = RlpNode :: encoded ( node) ;
7894 let hash = self . db . insert ( & node_rlp) ;
7995
96+ self . cache . insert ( hash, node_rlp) ;
8097 * old_val = Some ( value. to_vec ( ) ) ;
8198
8299 Ok ( hash)
@@ -102,6 +119,7 @@ impl<'a> TrieDBMut<'a> {
102119
103120 let node_rlp = RlpNode :: encoded_until ( RlpNode :: Branch ( partial, new_child. into ( ) ) , common) ;
104121 let hash = self . db . insert ( & node_rlp) ;
122+ self . cache . insert ( hash, node_rlp) ;
105123
106124 Ok ( hash)
107125 }
@@ -118,6 +136,7 @@ impl<'a> TrieDBMut<'a> {
118136
119137 let mut node_rlp = RlpNode :: encoded ( o_branch) ;
120138 let b_hash = self . db . insert ( & node_rlp) ;
139+ self . cache . insert ( b_hash, node_rlp) ;
121140
122141 new_child[ new_partial. at ( 0 ) as usize ] = Some ( b_hash) ;
123142 new_child[ new_path. at ( 0 ) as usize ] = Some ( self . insert_aux (
@@ -129,6 +148,7 @@ impl<'a> TrieDBMut<'a> {
129148
130149 node_rlp = RlpNode :: encoded_until ( RlpNode :: Branch ( partial, new_child. into ( ) ) , common) ;
131150 let hash = self . db . insert ( & node_rlp) ;
151+ self . cache . insert ( hash, node_rlp) ;
132152
133153 Ok ( hash)
134154 } else {
@@ -145,6 +165,7 @@ impl<'a> TrieDBMut<'a> {
145165 let new_branch = RlpNode :: Branch ( partial, children) ;
146166 let node_rlp = RlpNode :: encoded ( new_branch) ;
147167 let hash = self . db . insert ( & node_rlp) ;
168+ self . cache . insert ( hash, node_rlp) ;
148169
149170 Ok ( hash)
150171 }
@@ -153,6 +174,7 @@ impl<'a> TrieDBMut<'a> {
153174 let node = RlpNode :: Leaf ( path, insert_value) ;
154175 let node_rlp = RlpNode :: encoded ( node) ;
155176 let hash = self . db . insert ( & node_rlp) ;
177+ self . cache . insert ( hash, node_rlp) ;
156178
157179 Ok ( hash)
158180 }
@@ -162,6 +184,7 @@ impl<'a> TrieDBMut<'a> {
162184 let node = RlpNode :: Leaf ( path, insert_value) ;
163185 let node_rlp = RlpNode :: encoded ( node) ;
164186 let hash = self . db . insert ( & node_rlp) ;
187+ self . cache . insert ( hash, node_rlp) ;
165188
166189 Ok ( hash)
167190 }
0 commit comments