parallel-subtrees WORKING STATE
This commit is contained in:
parent
3817ddbec3
commit
8b0d7bd7b4
2 changed files with 54 additions and 1 deletions
|
@ -11,7 +11,7 @@ use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError,
|
||||||
/// The position is represented by the pair `(depth, pos)`, where for a given depth `d` elements
|
/// The position is represented by the pair `(depth, pos)`, where for a given depth `d` elements
|
||||||
/// are numbered from $0..(2^d)-1$. Example:
|
/// are numbered from $0..(2^d)-1$. Example:
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```text
|
||||||
/// depth
|
/// depth
|
||||||
/// 0 0
|
/// 0 0
|
||||||
/// 1 0 1
|
/// 1 0 1
|
||||||
|
@ -72,6 +72,37 @@ impl NodeIndex {
|
||||||
Self::new(depth, value)
|
Self::new(depth, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts a row traversal index to depth-value form and returns it as a [`NodeIndex`].
|
||||||
|
/// See [`NodeIndex::to_traversal_index()`] for more details.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// Returns the same errors under the same conditions as [`NodeIndex::new()`].
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// Panics if the depth indicated by `index` does not fit in a [`u8`], or if the row-value
|
||||||
|
/// indicated by `index` does not fit in a [`u64`].
|
||||||
|
pub const fn from_traversal_index(index: u128) -> Result<Self, MerkleError> {
|
||||||
|
if index == 0 {
|
||||||
|
return Ok(Self { depth: 0, value: 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
let depth = {
|
||||||
|
let depth = u128::ilog2(index);
|
||||||
|
assert!(depth <= u8::MAX as u32);
|
||||||
|
depth as u8
|
||||||
|
};
|
||||||
|
|
||||||
|
let max_index_for_depth = u128::pow(2, depth as u32) - 1;
|
||||||
|
|
||||||
|
let value = {
|
||||||
|
let value = index - max_index_for_depth;
|
||||||
|
assert!(value <= u64::MAX as u128);
|
||||||
|
value as u64
|
||||||
|
};
|
||||||
|
|
||||||
|
Self::new(depth, value)
|
||||||
|
}
|
||||||
|
|
||||||
/// Converts a scalar representation of a depth/value pair to a [`NodeIndex`].
|
/// Converts a scalar representation of a depth/value pair to a [`NodeIndex`].
|
||||||
///
|
///
|
||||||
/// This is the inverse operation of [`NodeIndex::to_scalar_index()`]. As `1` represents the
|
/// This is the inverse operation of [`NodeIndex::to_scalar_index()`]. As `1` represents the
|
||||||
|
@ -233,11 +264,13 @@ impl NodeIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the depth of the current instance.
|
/// Returns the depth of the current instance.
|
||||||
|
#[inline(always)]
|
||||||
pub const fn depth(&self) -> u8 {
|
pub const fn depth(&self) -> u8 {
|
||||||
self.depth
|
self.depth
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the value of this index.
|
/// Returns the value of this index.
|
||||||
|
#[inline(always)]
|
||||||
pub const fn value(&self) -> u64 {
|
pub const fn value(&self) -> u64 {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
@ -248,10 +281,26 @@ impl NodeIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the depth is `0`.
|
/// Returns `true` if the depth is `0`.
|
||||||
|
#[inline(always)]
|
||||||
pub const fn is_root(&self) -> bool {
|
pub const fn is_root(&self) -> bool {
|
||||||
self.depth == 0
|
self.depth == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts this [`NodeIndex`] to the equivalent row traversal index (also called level order
|
||||||
|
/// traversal index or breadth-first order index).
|
||||||
|
///
|
||||||
|
/// [`NodeIndex`] denotes a node position by its depth and the index in the row at that depth.
|
||||||
|
/// The row traversal index denotes a node position by counting all the nodes "before" it --
|
||||||
|
/// counting all nodes before it in the row, as well as all nodes in all other rows above it.
|
||||||
|
/// In other words, a node at row traversal index `n` is the `n`th node in the tree.
|
||||||
|
/// For example, a node at depth `2`, value `3` has the root node `0, 0`, its two children
|
||||||
|
/// `1, 0` and `1, 1`, and their children `2, 0`, `2, 1`, `2, 2`, and `2, 3`, 0-indexed, `2, 3`
|
||||||
|
/// is node **`6`** in that order, so its row traversal index is `6`.
|
||||||
|
pub const fn to_traversal_index(&self) -> u128 {
|
||||||
|
(1 << self.depth) - 1 + (self.value as u128)
|
||||||
|
//u128::pow(2, self.depth as u32) - 1 + (self.value as u128)
|
||||||
|
}
|
||||||
|
|
||||||
// STATE MUTATORS
|
// STATE MUTATORS
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -560,6 +560,8 @@ pub(crate) struct NodeSubtreeState<const DEPTH: u8> {
|
||||||
cached_leaf_hashes: HashMap<LeafIndex<SMT_DEPTH>, RpoDigest>,
|
cached_leaf_hashes: HashMap<LeafIndex<SMT_DEPTH>, RpoDigest>,
|
||||||
indentation: u8,
|
indentation: u8,
|
||||||
subtree: SubtreeIndex,
|
subtree: SubtreeIndex,
|
||||||
|
dirty_high: u128,
|
||||||
|
dirty_low: u128,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
|
@ -581,6 +583,8 @@ impl<const DEPTH: u8> NodeSubtreeState<DEPTH> {
|
||||||
cached_leaf_hashes: Default::default(),
|
cached_leaf_hashes: Default::default(),
|
||||||
indentation: 0,
|
indentation: 0,
|
||||||
subtree,
|
subtree,
|
||||||
|
dirty_high: 0,
|
||||||
|
dirty_low: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue