cfx_storage/impls/delta_mpt/row_number.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
5use super::super::errors::*;
6// TODO: make it Delta MPT only. Add another type for Persistent MPT later.
7#[cfg(not(feature = "u64_mpt_db_key"))]
8pub type RowNumberUnderlyingType = u32;
9#[cfg(feature = "u64_mpt_db_key")]
10pub type RowNumberUnderlyingType = u64;
11/// Because the Merkle Hash is too large to store for links to children in MPT,
12/// and it's only useful for persistence, in delta MPT we use row number as
13/// storage key.
14///
15/// Using RowNumber as node index is also more space/time efficient than other
16/// Maps in standard library, given that our goal of
17#[derive(Copy, Clone, Default)]
18pub struct RowNumber {
19 pub value: RowNumberUnderlyingType,
20}
21
22impl RowNumber {
23 /// Cap at `2^(BITS-1) - 1` (2^31-1 for u32, 2^63-1 for u64): the compact
24 /// node ref (`node_ref.rs`) reserves the top bit of a committed db_key for
25 /// its persistent-key encoding, so a db_key must keep its MSB clear, and
26 /// this is the largest value that does.
27 pub const ROW_NUMBER_LIMIT: RowNumberUnderlyingType =
28 (1 << (RowNumberUnderlyingType::BITS - 1)) - 1;
29
30 pub fn get_next(&self) -> Result<RowNumber> {
31 if self.value != Self::ROW_NUMBER_LIMIT {
32 Ok(Self {
33 value: self.value + 1,
34 })
35 } else {
36 Err(Error::MPTTooManyNodes.into())
37 }
38 }
39}
40
41impl ToString for RowNumber {
42 fn to_string(&self) -> String { self.value.to_string() }
43}