shardtree: Minor cleanups & documentation improvements.

This commit is contained in:
Kris Nuttycombe 2024-06-25 15:04:12 -06:00
parent f5adcd5a2c
commit b38b9d5d62
5 changed files with 20 additions and 26 deletions

View File

@ -9,6 +9,7 @@ and this project adheres to Rust's notion of
### Added ### Added
- `incrementalmerkletree::Marking` - `incrementalmerkletree::Marking`
- `incrementalmerkletree::Level::ZERO`
### Changed ### Changed
- `incrementalmerkletree::Retention` - `incrementalmerkletree::Retention`

View File

@ -280,6 +280,9 @@ impl TryFrom<Position> for usize {
pub struct Level(u8); pub struct Level(u8);
impl Level { impl Level {
/// Level 0 corresponds to a leaf of the tree.
pub const ZERO: Self = Level(0);
pub const fn new(value: u8) -> Self { pub const fn new(value: u8) -> Self {
Self(value) Self(value)
} }

View File

@ -210,7 +210,8 @@ impl<
Ok(()) Ok(())
} }
/// Append a single value at the first available position in the tree. /// Append a single value at the first unfilled position greater than the maximum position of
/// any previously inserted leaf.
/// ///
/// Prefer to use [`Self::batch_insert`] when appending multiple values, as these operations /// Prefer to use [`Self::batch_insert`] when appending multiple values, as these operations
/// require fewer traversals of the tree than are necessary when performing multiple sequential /// require fewer traversals of the tree than are necessary when performing multiple sequential
@ -320,17 +321,8 @@ impl<
.map_err(ShardTreeError::Storage)? .map_err(ShardTreeError::Storage)?
.unwrap_or_else(|| LocatedTree::empty(subtree_root_addr)); .unwrap_or_else(|| LocatedTree::empty(subtree_root_addr));
trace!(
max_position = ?current_shard.max_position(),
subtree = ?current_shard,
"Current shard");
let (updated_subtree, supertree) = let (updated_subtree, supertree) =
current_shard.insert_frontier_nodes(frontier, &leaf_retention)?; current_shard.insert_frontier_nodes(frontier, &leaf_retention)?;
trace!(
max_position = ?updated_subtree.max_position(),
subtree = ?updated_subtree,
"Replacement shard"
);
self.store self.store
.put_shard(updated_subtree) .put_shard(updated_subtree)
.map_err(ShardTreeError::Storage)?; .map_err(ShardTreeError::Storage)?;
@ -1464,7 +1456,8 @@ mod tests {
id: 1, id: 1,
marking: frontier_marking, marking: frontier_marking,
}, },
)?; )
.unwrap();
// Insert a few leaves beginning at the subsequent position, so as to cross the shard // Insert a few leaves beginning at the subsequent position, so as to cross the shard
// boundary. // boundary.
@ -1473,7 +1466,8 @@ mod tests {
('g'..='j') ('g'..='j')
.into_iter() .into_iter()
.map(|c| (c.to_string(), Retention::Ephemeral)), .map(|c| (c.to_string(), Retention::Ephemeral)),
)?; )
.unwrap();
// Trigger pruning by adding 5 more checkpoints // Trigger pruning by adding 5 more checkpoints
for i in 2..7 { for i in 2..7 {
@ -1486,7 +1480,8 @@ mod tests {
('e'..='f') ('e'..='f')
.into_iter() .into_iter()
.map(|c| (c.to_string(), Retention::Marked)), .map(|c| (c.to_string(), Retention::Marked)),
)?; )
.unwrap();
// Compute the witness // Compute the witness
tree.witness_at_checkpoint_id(frontier_end, &6) tree.witness_at_checkpoint_id(frontier_end, &6)

View File

@ -322,11 +322,7 @@ impl<H: Hashable + Clone + PartialEq> PrunableTree<H> {
{ {
Tree::leaf((H::combine(level, &lv.0, &rv.0), rv.1)) Tree::leaf((H::combine(level, &lv.0, &rv.0), rv.1))
} }
(left, right) => Tree::parent( (left, right) => Tree::parent(ann, left, right),
ann,
left,
right,
),
} }
} }
} }
@ -563,12 +559,6 @@ impl<H: Hashable + Clone + PartialEq> LocatedPrunableTree<H> {
subtree: LocatedPrunableTree<H>, subtree: LocatedPrunableTree<H>,
contains_marked: bool, contains_marked: bool,
) -> Result<(PrunableTree<H>, Vec<IncompleteAt>), InsertionError> { ) -> Result<(PrunableTree<H>, Vec<IncompleteAt>), InsertionError> {
trace!(
root_addr = ?root_addr,
max_position = ?LocatedTree::max_position_internal(root_addr, into),
to_insert = ?subtree.root_addr(),
"Subtree insert"
);
// An empty tree cannot replace any other type of tree. // An empty tree cannot replace any other type of tree.
if subtree.root().is_nil() { if subtree.root().is_nil() {
Ok((into.clone(), vec![])) Ok((into.clone(), vec![]))

View File

@ -94,7 +94,9 @@ impl<A, V> Deref for Tree<A, V> {
impl<A, V> Tree<A, V> { impl<A, V> Tree<A, V> {
/// Constructs the empty tree. /// Constructs the empty tree.
pub fn empty() -> Self { ///
/// This represents a tree for which we have no information.
pub const fn empty() -> Self {
Tree(Node::Nil) Tree(Node::Nil)
} }
@ -104,6 +106,9 @@ impl<A, V> Tree<A, V> {
} }
/// Constructs a tree containing a single leaf. /// Constructs a tree containing a single leaf.
///
/// This represents either leaf of the tree, or an internal parent node of the
/// tree having all [`Node::Pruned`] children.
pub fn leaf(value: V) -> Self { pub fn leaf(value: V) -> Self {
Tree(Node::Leaf { value }) Tree(Node::Leaf { value })
} }
@ -117,7 +122,7 @@ impl<A, V> Tree<A, V> {
}) })
} }
/// Returns `true` if the tree has no leaves. /// Returns `true` if the tree is the [`Node::Nil`] node.
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.0.is_nil() self.0.is_nil()
} }