mirror of
https://github.com/vacp2p/pmtree.git
synced 2025-02-22 12:08:31 +00:00
feat: batch ops
This commit is contained in:
parent
b3a02216ce
commit
93ccd0b594
56
src/tree.rs
56
src/tree.rs
@ -250,6 +250,62 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn batch_operations<I: IntoIterator<Item = H::Fr>, J: IntoIterator<Item = usize>>(
|
||||
&mut self,
|
||||
leaves: I,
|
||||
to_remove_indices: J,
|
||||
) -> PmtreeResult<()> {
|
||||
let leaves = leaves.into_iter().collect::<Vec<_>>();
|
||||
let to_remove_indices = to_remove_indices.into_iter().collect::<Vec<_>>();
|
||||
|
||||
let start = self.next_index;
|
||||
let end = start + leaves.len();
|
||||
|
||||
if end - to_remove_indices.len() > self.capacity() {
|
||||
return Err(PmtreeErrorKind::TreeError(TreeErrorKind::MerkleTreeIsFull));
|
||||
}
|
||||
|
||||
let mut subtree = HashMap::<Key, H::Fr>::new();
|
||||
|
||||
let root_key = Key(0, 0);
|
||||
|
||||
subtree.insert(root_key, self.root);
|
||||
self.fill_nodes(root_key, start, end, &mut subtree, &leaves, start)?;
|
||||
|
||||
for i in to_remove_indices {
|
||||
subtree.insert(Key(self.depth, i), H::default_leaf());
|
||||
}
|
||||
|
||||
let subtree = Arc::new(RwLock::new(subtree));
|
||||
|
||||
let root_val = rayon::ThreadPoolBuilder::new()
|
||||
.num_threads(rayon::current_num_threads())
|
||||
.build()
|
||||
.unwrap()
|
||||
.install(|| Self::batch_recalculate(root_key, Arc::clone(&subtree), self.depth));
|
||||
|
||||
let subtree = RwLock::into_inner(Arc::try_unwrap(subtree).unwrap()).unwrap();
|
||||
|
||||
self.db.put_batch(
|
||||
subtree
|
||||
.into_iter()
|
||||
.map(|(key, value)| (key.into(), H::serialize(value)))
|
||||
.collect(),
|
||||
)?;
|
||||
|
||||
// Update next_index value in db
|
||||
if end > self.next_index {
|
||||
self.next_index = end;
|
||||
self.db
|
||||
.put(NEXT_INDEX_KEY, self.next_index.to_be_bytes().to_vec())?;
|
||||
}
|
||||
|
||||
// Update root value in memory
|
||||
self.root = root_val;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Fills hashmap subtree
|
||||
fn fill_nodes(
|
||||
&self,
|
||||
|
@ -196,3 +196,48 @@ fn set_range() -> PmtreeResult<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_operations() -> PmtreeResult<()> {
|
||||
let mut mt = MerkleTree::<MySled, MyKeccak>::new(
|
||||
2,
|
||||
SledConfig {
|
||||
path: String::from("batch_operations"),
|
||||
},
|
||||
)?;
|
||||
|
||||
let leaves = [
|
||||
hex!("0000000000000000000000000000000000000000000000000000000000000001"),
|
||||
hex!("0000000000000000000000000000000000000000000000000000000000000002"),
|
||||
];
|
||||
|
||||
mt.batch_insert(None, &leaves)?;
|
||||
|
||||
assert_eq!(
|
||||
mt.root(),
|
||||
hex!("893760ec5b5bee236f29e85aef64f17139c3c1b7ff24ce64eb6315fca0f2485b")
|
||||
);
|
||||
|
||||
let leaves = [
|
||||
hex!("0000000000000000000000000000000000000000000000000000000000000003"),
|
||||
hex!("0000000000000000000000000000000000000000000000000000000000000004"),
|
||||
];
|
||||
|
||||
mt.batch_operations(leaves, [])?;
|
||||
|
||||
assert_eq!(
|
||||
mt.root(),
|
||||
hex!("a9bb8c3f1f12e9aa903a50c47f314b57610a3ab32f2d463293f58836def38d36")
|
||||
);
|
||||
|
||||
mt.batch_operations([], [0, 1, 2, 3])?;
|
||||
|
||||
assert_eq!(
|
||||
mt.root(),
|
||||
hex!("b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30")
|
||||
);
|
||||
|
||||
fs::remove_dir_all("batch_operations").expect("Error removing db");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user