cfx_storage/impls/delta_mpt/
node_ref.rs1pub type CompactNodeRef = RowNumberUnderlyingType;
6
7#[derive(Copy, Clone, Debug, Eq, PartialEq, MallocSizeOfDerive)]
14pub struct NodeRefDeltaMptCompact {
15 value: CompactNodeRef,
16}
17
18impl NodeRefTrait for NodeRefDeltaMptCompact {}
19
20#[derive(Copy, Clone, Debug, Eq, PartialEq, MallocSizeOfDerive)]
21pub struct MaybeNodeRefDeltaMptCompact {
22 value: CompactNodeRef,
23}
24
25impl Default for MaybeNodeRefDeltaMptCompact {
26 fn default() -> Self { Self { value: Self::NULL } }
27}
28
29impl NodeRefDeltaMptCompact {
30 pub const DIRTY_SLOT_LIMIT: u32 = 0x7fffffff;
33 const LARGE_PERSISTENT_KEY_BIT: CompactNodeRef =
34 1 << (CompactNodeRef::BITS - 1);
35 const PERSISTENT_KEY_BIT: CompactNodeRef = 0x80000000;
38
39 pub fn new(value: CompactNodeRef) -> Self { Self { value } }
40}
41
42impl MaybeNodeRefDeltaMptCompact {
43 pub const NULL: CompactNodeRef = 0;
44 pub const NULL_NODE: MaybeNodeRefDeltaMptCompact =
45 MaybeNodeRefDeltaMptCompact { value: Self::NULL };
46
47 pub fn new(value: CompactNodeRef) -> Self { Self { value } }
48}
49
50#[derive(Clone, Eq, PartialOrd, PartialEq, Ord, Debug, MallocSizeOfDerive)]
53pub enum NodeRefDeltaMpt {
54 Committed { db_key: DeltaMptDbKey },
55 Dirty { index: ActualSlabIndex },
56}
57
58impl From<NodeRefDeltaMpt> for NodeRefDeltaMptCompact {
59 fn from(node: NodeRefDeltaMpt) -> Self {
60 match node {
61 NodeRefDeltaMpt::Committed { db_key } => Self {
62 value: if db_key < NodeRefDeltaMptCompact::PERSISTENT_KEY_BIT {
63 db_key ^ NodeRefDeltaMptCompact::PERSISTENT_KEY_BIT
64 } else {
65 if cfg!(feature = "u64_mpt_db_key") {
66 db_key ^ NodeRefDeltaMptCompact::PERSISTENT_KEY_BIT
67 | NodeRefDeltaMptCompact::LARGE_PERSISTENT_KEY_BIT
68 } else {
69 unreachable!("should not run large state with u32 key")
70 }
71 },
72 },
73 NodeRefDeltaMpt::Dirty { index } => Self {
74 value: (index ^ NodeRefDeltaMptCompact::DIRTY_SLOT_LIMIT)
75 as CompactNodeRef,
76 },
77 }
78 }
79}
80
81impl From<NodeRefDeltaMptCompact> for NodeRefDeltaMpt {
82 fn from(x: NodeRefDeltaMptCompact) -> Self {
83 if NodeRefDeltaMptCompact::PERSISTENT_KEY_BIT & x.value == 0
84 && (NodeRefDeltaMptCompact::LARGE_PERSISTENT_KEY_BIT as CompactNodeRef) & x.value == 0
86 {
87 NodeRefDeltaMpt::Dirty {
88 index: (NodeRefDeltaMptCompact::DIRTY_SLOT_LIMIT
89 ^ x.value as u32),
90 }
91 } else {
92 NodeRefDeltaMpt::Committed {
93 db_key: (NodeRefDeltaMptCompact::PERSISTENT_KEY_BIT ^ x.value)
94 & !NodeRefDeltaMptCompact::LARGE_PERSISTENT_KEY_BIT,
95 }
96 }
97 }
98}
99
100impl From<MaybeNodeRefDeltaMptCompact> for Option<NodeRefDeltaMpt> {
101 fn from(x: MaybeNodeRefDeltaMptCompact) -> Self {
102 if x.value == MaybeNodeRefDeltaMptCompact::NULL {
103 None
104 } else {
105 Some(NodeRefDeltaMptCompact::new(x.value).into())
106 }
107 }
108}
109
110impl From<Option<NodeRefDeltaMpt>> for MaybeNodeRefDeltaMptCompact {
111 fn from(maybe_node: Option<NodeRefDeltaMpt>) -> Self {
112 match maybe_node {
113 None => MaybeNodeRefDeltaMptCompact::NULL_NODE,
114 Some(node) => MaybeNodeRefDeltaMptCompact::new(
115 NodeRefDeltaMptCompact::from(node).value,
116 ),
117 }
118 }
119}
120
121impl Decodable for NodeRefDeltaMptCompact {
122 fn decode(rlp: &Rlp) -> ::std::result::Result<Self, DecoderError> {
123 Ok(NodeRefDeltaMptCompact {
124 value: rlp.as_val()?,
125 })
126 }
127}
128
129impl Encodable for NodeRefDeltaMptCompact {
130 fn rlp_append(&self, s: &mut RlpStream) { s.append_internal(&self.value); }
131}
132
133use super::{
134 super::merkle_patricia_trie::NodeRefTrait,
135 node_memory_manager::ActualSlabIndex, node_ref_map::DeltaMptDbKey,
136};
137use crate::impls::delta_mpt::row_number::RowNumberUnderlyingType;
138use malloc_size_of_derive::MallocSizeOf as MallocSizeOfDerive;
139use rlp::*;
140
141#[test]
142#[cfg(feature = "u64_mpt_db_key")]
143fn test_large_key() {
144 let db_key = NodeRefDeltaMpt::Committed { db_key: (1 << 32) };
145 let compact: NodeRefDeltaMptCompact = db_key.clone().into();
146 let a = match db_key {
147 NodeRefDeltaMpt::Committed { db_key } => db_key,
148 _ => unreachable!(),
149 };
150 let b = match NodeRefDeltaMpt::from(compact) {
151 NodeRefDeltaMpt::Committed { db_key } => db_key,
152 _ => unreachable!(),
153 };
154 assert_eq!(a.to_be_bytes(), b.to_be_bytes());
155}