cfx_storage/impls/delta_mpt/
owned_node_set.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5/// A container to store information about owned nodes.
6#[derive(Default, Debug)]
7pub struct OwnedNodeSet {
8    dirty: BTreeMap<ActualSlabIndex, Option<DeltaMptDbKey>>,
9    committed: BTreeSet<DeltaMptDbKey>,
10}
11
12impl OwnedNodeSet {
13    /// Insertion takes an extra argument `original_db_key` to
14    /// indicate where a dirty node comes from.  If it's a new node,
15    /// pass None.  If it's a committed node, the argument is ignored.
16    pub fn insert(
17        &mut self, val: NodeRefDeltaMpt, original_db_key: Option<DeltaMptDbKey>,
18    ) -> bool {
19        match val {
20            NodeRefDeltaMpt::Committed { db_key } => {
21                self.committed.insert(db_key)
22            }
23            NodeRefDeltaMpt::Dirty { index } => {
24                self.dirty.insert(index, original_db_key).is_none()
25            }
26        }
27    }
28
29    pub fn remove(&mut self, val: &NodeRefDeltaMpt) -> bool {
30        match val {
31            NodeRefDeltaMpt::Committed { db_key } => {
32                self.committed.remove(db_key)
33            }
34            NodeRefDeltaMpt::Dirty { index, .. } => {
35                self.dirty.remove(index).is_some()
36            }
37        }
38    }
39
40    pub fn contains(&self, val: &NodeRefDeltaMpt) -> bool {
41        match val {
42            NodeRefDeltaMpt::Committed { db_key } => {
43                self.committed.contains(db_key)
44            }
45            NodeRefDeltaMpt::Dirty { index, .. } => {
46                self.dirty.contains_key(index)
47            }
48        }
49    }
50
51    pub fn iter(&self) -> Iter<'_> {
52        Iter {
53            dirty_iter: self.dirty.iter().fuse(),
54            committed_iter: self.committed.iter().fuse(),
55        }
56    }
57
58    pub fn get_original_db_key(
59        &self, index: ActualSlabIndex,
60    ) -> Option<DeltaMptDbKey> {
61        match self.dirty.get(&index).cloned() {
62            Some(Some(index)) => Some(index),
63            _ => None,
64        }
65    }
66}
67
68pub struct Iter<'a> {
69    committed_iter:
70        std::iter::Fuse<std::collections::btree_set::Iter<'a, DeltaMptDbKey>>,
71    dirty_iter: std::iter::Fuse<
72        std::collections::btree_map::Iter<
73            'a,
74            ActualSlabIndex,
75            Option<DeltaMptDbKey>,
76        >,
77    >,
78}
79
80impl<'a> Iterator for Iter<'a> {
81    type Item = NodeRefDeltaMpt;
82
83    fn next(&mut self) -> Option<Self::Item> {
84        if let Some(dirty) = self.dirty_iter.next() {
85            return Some(NodeRefDeltaMpt::Dirty { index: *dirty.0 });
86        }
87
88        if let Some(committed) = self.committed_iter.next() {
89            return Some(NodeRefDeltaMpt::Committed { db_key: *committed });
90        }
91
92        return None;
93    }
94}
95
96impl<'a> IntoIterator for &'a OwnedNodeSet {
97    type IntoIter = Iter<'a>;
98    type Item = NodeRefDeltaMpt;
99
100    fn into_iter(self) -> Iter<'a> { self.iter() }
101}
102
103use super::{
104    node_memory_manager::ActualSlabIndex, node_ref_map::DeltaMptDbKey,
105    NodeRefDeltaMpt,
106};
107use std::collections::{BTreeMap, BTreeSet};