use alloc::vec::Vec;
use crate::{
Word,
merkle::smt::{
full::SMT_DEPTH,
large_forest::{
backend::Backend,
root::{LineageId, TreeWithRoot, VersionId},
},
},
};
pub type MutationSet = crate::merkle::smt::MutationSet<SMT_DEPTH, Word, Word>;
pub struct SmtForestMutationSet<B: Backend> {
entries: Vec<LineageMutation>,
prepared: B::PreparedMutations,
}
impl<B: Backend> SmtForestMutationSet<B> {
pub(crate) fn new(entries: Vec<LineageMutation>, prepared: B::PreparedMutations) -> Self {
Self { entries, prepared }
}
pub fn lineage_mutations(&self) -> &[LineageMutation] {
&self.entries
}
pub fn roots(&self) -> impl Iterator<Item = TreeWithRoot> + '_ {
self.entries.iter().map(LineageMutation::result)
}
pub(crate) fn into_parts(self) -> (Vec<LineageMutation>, B::PreparedMutations) {
(self.entries, self.prepared)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct LineageMutation {
lineage: LineageId,
old_version: Option<VersionId>,
new_version: VersionId,
old_root: Word,
new_root: Word,
kind: LineageMutationKind,
}
impl LineageMutation {
pub(crate) fn new(
lineage: LineageId,
old_version: Option<VersionId>,
new_version: VersionId,
old_root: Word,
new_root: Word,
kind: LineageMutationKind,
) -> Self {
Self {
lineage,
old_version,
new_version,
old_root,
new_root,
kind,
}
}
pub fn lineage(&self) -> LineageId {
self.lineage
}
pub fn old_version(&self) -> Option<VersionId> {
self.old_version
}
pub fn new_version(&self) -> VersionId {
self.new_version
}
pub fn old_root(&self) -> Word {
self.old_root
}
pub fn new_root(&self) -> Word {
self.new_root
}
pub fn kind(&self) -> LineageMutationKind {
self.kind
}
pub fn result(&self) -> TreeWithRoot {
let version =
if self.kind == LineageMutationKind::UpdateTree && self.old_root == self.new_root {
self.old_version.expect("update tree mutations always have an old version")
} else {
self.new_version
};
TreeWithRoot::new(self.lineage, version, self.new_root)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AppliedLineageMutation {
lineage: LineageId,
old_version: Option<VersionId>,
new_version: VersionId,
old_root: Word,
new_root: Word,
old_entry_count: usize,
reverse: MutationSet,
kind: LineageMutationKind,
}
impl AppliedLineageMutation {
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
lineage: LineageId,
old_version: Option<VersionId>,
new_version: VersionId,
old_root: Word,
new_root: Word,
old_entry_count: usize,
reverse: MutationSet,
kind: LineageMutationKind,
) -> Self {
Self {
lineage,
old_version,
new_version,
old_root,
new_root,
old_entry_count,
reverse,
kind,
}
}
pub fn lineage(&self) -> LineageId {
self.lineage
}
pub fn old_version(&self) -> Option<VersionId> {
self.old_version
}
pub fn new_version(&self) -> VersionId {
self.new_version
}
pub fn old_root(&self) -> Word {
self.old_root
}
pub fn new_root(&self) -> Word {
self.new_root
}
pub fn old_entry_count(&self) -> usize {
self.old_entry_count
}
pub fn reverse(&self) -> &MutationSet {
&self.reverse
}
pub(crate) fn into_reverse(self) -> MutationSet {
self.reverse
}
pub fn kind(&self) -> LineageMutationKind {
self.kind
}
pub fn result(&self) -> TreeWithRoot {
let version =
if self.kind == LineageMutationKind::UpdateTree && self.old_root == self.new_root {
self.old_version.expect("update tree mutations always have an old version")
} else {
self.new_version
};
TreeWithRoot::new(self.lineage, version, self.new_root)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LineageMutationKind {
AddLineage,
UpdateTree,
}