trie_test/database/
mod.rs1mod memory;
2
3use super::{SecureTrie, FixedTrie, FixedSecureTrie, Trie};
4
5pub use self::memory::{MemoryDatabase, MemoryDatabaseGuard};
6
7use bigint::H256;
8use rlp;
9use std::collections::HashMap;
10use std::cell::RefCell;
11
12pub trait Database<'a> {
13 type Guard: DatabaseGuard + 'a;
14
15 fn create_guard(&'a self) -> Self::Guard;
16 fn create_trie(&'a self, root: H256) -> Trie<Self::Guard> {
17 Trie::existing(self.create_guard(), root)
18 }
19 fn create_empty(&'a self) -> Trie<Self::Guard> {
20 self.create_trie(empty_trie_hash!())
21 }
22 fn create_secure_trie(&'a self, root: H256) -> SecureTrie<Self::Guard> {
23 SecureTrie::new(self.create_trie(root))
24 }
25 fn create_secure_empty(&'a self) -> SecureTrie<Self::Guard> {
26 SecureTrie::new(self.create_empty())
27 }
28 fn create_fixed_trie<K: rlp::Encodable + rlp::Decodable, V: rlp::Encodable + rlp::Decodable>(&'a self, root: H256) -> FixedTrie<Self::Guard, K, V> {
29 FixedTrie::new(self.create_trie(root))
30 }
31 fn create_fixed_empty<K: rlp::Encodable + rlp::Decodable, V: rlp::Encodable + rlp::Decodable>(&'a self) -> FixedTrie<Self::Guard, K, V> {
32 FixedTrie::new(self.create_empty())
33 }
34 fn create_fixed_secure_trie<K: AsRef<[u8]>, V: rlp::Encodable + rlp::Decodable>(&'a self, root: H256) -> FixedSecureTrie<Self::Guard, K, V> {
35 FixedSecureTrie::new(self.create_secure_trie(root))
36 }
37 fn create_fixed_secure_empty<K: AsRef<[u8]>, V: rlp::Encodable + rlp::Decodable>(&'a self) -> FixedSecureTrie<Self::Guard, K, V> {
38 FixedSecureTrie::new(self.create_secure_empty())
39 }
40}
41
42pub trait DatabaseOwned: for<'a> Database<'a> {}
43impl<T> DatabaseOwned for T where T: for<'a> Database<'a> {}
44
45pub trait DatabaseGuard {
46 fn get(&self, hash: H256) -> Option<Vec<u8>>;
47 fn set(&mut self, hash: H256, value: Vec<u8>);
48}
49
50impl DatabaseGuard for HashMap<H256, Vec<u8>> {
51 fn get<'a>(&'a self, hash: H256) -> Option<Vec<u8>> {
52 self.get(&hash).map(|v| v.clone())
53 }
54
55 fn set<'a>(&'a mut self, hash: H256, value: Vec<u8>) {
56 self.insert(hash, value);
57 }
58}
59
60pub struct Change<'a, D: 'a> {
61 database: &'a D,
62 cache: RefCell<HashMap<H256, Vec<u8>>>,
63
64 inserted: Vec<H256>,
65 freed: Vec<H256>,
66}
67
68impl<'a, D: DatabaseGuard> Change<'a, D> {
69 pub fn new(database: &'a D) -> Self {
70 Self {
71 database,
72 cache: RefCell::new(HashMap::new()),
73
74 inserted: Vec::new(),
75 freed: Vec::new(),
76 }
77 }
78
79 pub fn get<'b>(&'b self, hash: H256) -> Option<Vec<u8>> {
80 if self.cache.borrow().contains_key(&hash) {
81 self.cache.borrow().get(&hash).map(|v| v.clone())
82 } else {
83 let val = self.database.get(hash);
84 if val.is_some() {
85 self.cache.borrow_mut().insert(hash, val.clone().unwrap());
86 }
87 val
88 }
89 }
90
91 pub fn set<'b, 'c>(&'b mut self, hash: H256, value: Vec<u8>) {
92 self.cache.borrow_mut().insert(hash, value);
93 self.inserted.push(hash);
94 }
95
96 pub fn free<'b>(&'b mut self, hash: H256) {
97 self.freed.push(hash);
98 }
99
100 pub fn inserted<'b>(&'b self) -> &'b [H256] {
101 self.inserted.as_ref()
102 }
103
104 pub fn freed<'b>(&'b self) -> &'b [H256] {
105 self.freed.as_ref()
106 }
107}
108
109impl<'a, D: DatabaseGuard> From<Change<'a, D>> for ChangeSet {
110 fn from(val: Change<'a, D>) -> Self {
111 ChangeSet {
112 cache: val.cache,
113 inserted: val.inserted,
114 freed: val.freed,
115 }
116 }
117}
118
119pub struct ChangeSet {
120 cache: RefCell<HashMap<H256, Vec<u8>>>,
121
122 inserted: Vec<H256>,
123 freed: Vec<H256>,
124}
125
126impl ChangeSet {
127 pub fn drain<D: DatabaseGuard>(self, database: &mut D, nofree: bool) {
128 if !nofree { unimplemented!() }
129
130 for h in self.inserted {
131 database.set(h, self.cache.borrow().get(&h).unwrap().clone())
132 }
133 }
134}