Skip to main content

trie_memory/
gc.rs

1use bigint::H256;
2use trie::{Change, DatabaseHandle, get, insert, delete};
3use TrieMut;
4
5pub trait ItemCounter {
6    fn increase(&mut self, key: H256) -> usize;
7    fn decrease(&mut self, key: H256) -> usize;
8}
9
10pub trait DatabaseMut {
11    fn get(&self, key: H256) -> &[u8];
12    fn set(&mut self, key: H256, value: Option<&[u8]>);
13}
14
15struct DatabaseMutHandle<'a, D: DatabaseMut + 'a>(&'a D);
16
17impl<'a, D: DatabaseMut> DatabaseHandle for DatabaseMutHandle<'a, D> {
18    fn get(&self, key: H256) -> Option<&[u8]> {
19        Some(DatabaseMut::get(self.0, key))
20    }
21}
22
23pub struct TrieCollection<D: DatabaseMut, C: ItemCounter> {
24    database: D,
25    counter: C,
26}
27
28impl<D: DatabaseMut, C: ItemCounter> TrieCollection<D, C> {
29    pub fn new(database: D, counter: C) -> Self {
30        Self { database, counter }
31    }
32
33    pub fn trie_for<'a>(&'a self, root: H256) -> DatabaseTrieMut<'a, D> {
34        DatabaseTrieMut {
35            database: &self.database,
36            change: Change::default(),
37            root: root
38        }
39    }
40
41    pub fn apply<'a>(&'a mut self, trie: DatabaseTrieMut<'a, D>) {
42        for (key, value) in trie.change.adds {
43            self.database.set(key, Some(&value));
44            self.counter.increase(key);
45        }
46
47        for key in trie.change.removes {
48            let r = self.counter.decrease(key);
49            if r == 0 {
50                self.database.set(key, None);
51            }
52        }
53    }
54}
55
56pub struct DatabaseTrieMut<'a, D: DatabaseMut + 'a> {
57    database: &'a D,
58    change: Change,
59    root: H256,
60}
61
62impl<'a, D: DatabaseMut> TrieMut for DatabaseTrieMut<'a, D> {
63    fn root(&self) -> H256 {
64        self.root
65    }
66
67    fn insert(&mut self, key: &[u8], value: &[u8]) {
68        let (new_root, change) = insert(self.root, &DatabaseMutHandle(self.database), key, value).unwrap();
69
70        self.change.merge(&change);
71        self.root = new_root;
72    }
73
74    fn delete(&mut self, key: &[u8]) {
75        let (new_root, change) = delete(self.root, &DatabaseMutHandle(self.database), key).unwrap();
76
77        self.change.merge(&change);
78        self.root = new_root;
79    }
80
81    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
82        get(self.root, &DatabaseMutHandle(self.database), key).unwrap().map(|v| v.into())
83    }
84}