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}