parallel-subtrees WORKING STATE

This commit is contained in:
Qyriad 2024-10-31 13:21:26 -06:00
parent 3817ddbec3
commit 8b0d7bd7b4
2 changed files with 54 additions and 1 deletions

View file

@ -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
/// are numbered from $0..(2^d)-1$. Example:
///
/// ```ignore
/// ```text
/// depth
/// 0 0
/// 1 0 1
@ -72,6 +72,37 @@ impl NodeIndex {
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`].
///
/// 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.
#[inline(always)]
pub const fn depth(&self) -> u8 {
self.depth
}
/// Returns the value of this index.
#[inline(always)]
pub const fn value(&self) -> u64 {
self.value
}
@ -248,10 +281,26 @@ impl NodeIndex {
}
/// Returns `true` if the depth is `0`.
#[inline(always)]
pub const fn is_root(&self) -> bool {
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
// --------------------------------------------------------------------------------------------

View file

@ -560,6 +560,8 @@ pub(crate) struct NodeSubtreeState<const DEPTH: u8> {
cached_leaf_hashes: HashMap<LeafIndex<SMT_DEPTH>, RpoDigest>,
indentation: u8,
subtree: SubtreeIndex,
dirty_high: u128,
dirty_low: u128,
}
#[cfg(feature = "async")]
@ -581,6 +583,8 @@ impl<const DEPTH: u8> NodeSubtreeState<DEPTH> {
cached_leaf_hashes: Default::default(),
indentation: 0,
subtree,
dirty_high: 0,
dirty_low: 0,
}
}