0g-storage-node/common/append_merkle/src/node_manager.rs

209 lines
6.3 KiB
Rust
Raw Normal View History

2024-10-08 07:40:47 +00:00
use crate::HashElement;
use anyhow::Result;
2024-10-10 12:38:02 +00:00
use lru::LruCache;
use std::num::NonZeroUsize;
2024-10-08 07:40:47 +00:00
use std::sync::Arc;
use tracing::error;
pub struct NodeManager<E: HashElement> {
2024-10-10 12:38:02 +00:00
cache: LruCache<(usize, usize), E>,
2024-10-08 08:19:06 +00:00
layer_size: Vec<usize>,
2024-10-08 07:40:47 +00:00
db: Arc<dyn NodeDatabase<E>>,
2024-10-14 12:41:32 +00:00
db_tx: Option<Box<dyn NodeTransaction<E>>>,
2024-10-08 07:40:47 +00:00
}
impl<E: HashElement> NodeManager<E> {
pub fn new(db: Arc<dyn NodeDatabase<E>>, capacity: usize) -> Result<Self> {
let mut layer = 0;
let mut layer_size = Vec::new();
while let Some(size) = db.get_layer_size(layer)? {
layer_size.push(size);
layer += 1;
}
Ok(Self {
2024-10-10 12:38:02 +00:00
cache: LruCache::new(NonZeroUsize::new(capacity).expect("capacity should be non-zero")),
layer_size,
2024-10-08 07:40:47 +00:00
db,
2024-10-14 12:41:32 +00:00
db_tx: None,
})
2024-10-08 07:40:47 +00:00
}
2024-10-10 12:38:02 +00:00
pub fn new_dummy() -> Self {
Self {
cache: LruCache::unbounded(),
layer_size: vec![],
db: Arc::new(EmptyNodeDatabase {}),
2024-10-14 12:41:32 +00:00
db_tx: None,
2024-10-10 12:38:02 +00:00
}
}
2024-10-09 02:36:13 +00:00
pub fn push_node(&mut self, layer: usize, node: E) {
self.add_node(layer, self.layer_size[layer], node);
self.layer_size[layer] += 1;
}
pub fn append_nodes(&mut self, layer: usize, nodes: &[E]) {
let pos = &mut self.layer_size[layer];
let mut saved_nodes = Vec::with_capacity(nodes.len());
for node in nodes {
2024-10-10 12:38:02 +00:00
self.cache.put((layer, *pos), node.clone());
2024-10-09 02:36:13 +00:00
saved_nodes.push((layer, *pos, node));
*pos += 1;
}
2024-10-14 12:41:32 +00:00
let size = *pos;
self.db_tx().save_layer_size(layer, size);
self.db_tx().save_node_list(&saved_nodes);
2024-10-09 02:36:13 +00:00
}
2024-10-08 07:40:47 +00:00
pub fn get_node(&self, layer: usize, pos: usize) -> Option<E> {
2024-10-10 12:38:02 +00:00
match self.cache.peek(&(layer, pos)) {
2024-10-08 07:40:47 +00:00
Some(node) => Some(node.clone()),
None => self.db.get_node(layer, pos).unwrap_or_else(|e| {
error!("Failed to get node: {}", e);
None
}),
}
}
2024-10-09 02:36:13 +00:00
pub fn get_nodes(&self, layer: usize, start_pos: usize, end_pos: usize) -> NodeIterator<E> {
NodeIterator {
2024-10-10 12:50:30 +00:00
node_manager: self,
2024-10-09 02:36:13 +00:00
layer,
start_pos,
end_pos,
}
}
2024-10-08 07:40:47 +00:00
pub fn add_node(&mut self, layer: usize, pos: usize, node: E) {
2024-10-14 12:41:32 +00:00
// No need to insert if the value is unchanged.
if self.cache.get(&(layer, pos)) != Some(&node) {
self.db_tx().save_node(layer, pos, &node);
self.cache.put((layer, pos), node);
2024-10-08 07:40:47 +00:00
}
2024-10-08 08:19:06 +00:00
}
pub fn add_layer(&mut self) {
self.layer_size.push(0);
2024-10-14 12:41:32 +00:00
let layer = self.layer_size.len() - 1;
self.db_tx().save_layer_size(layer, 0);
2024-10-08 08:19:06 +00:00
}
pub fn layer_size(&self, layer: usize) -> usize {
self.layer_size[layer]
}
pub fn num_layers(&self) -> usize {
self.layer_size.len()
2024-10-08 07:40:47 +00:00
}
2024-10-09 02:36:13 +00:00
pub fn truncate_nodes(&mut self, layer: usize, pos_end: usize) {
let mut removed_nodes = Vec::new();
for pos in pos_end..self.layer_size[layer] {
2024-10-10 12:38:02 +00:00
self.cache.pop(&(layer, pos));
2024-10-09 02:36:13 +00:00
removed_nodes.push((layer, pos));
}
2024-10-14 12:41:32 +00:00
self.db_tx().remove_node_list(&removed_nodes);
2024-10-09 02:36:13 +00:00
self.layer_size[layer] = pos_end;
2024-10-14 12:41:32 +00:00
self.db_tx().save_layer_size(layer, pos_end);
2024-10-09 02:36:13 +00:00
}
pub fn truncate_layer(&mut self, layer: usize) {
self.truncate_nodes(layer, 0);
if layer == self.num_layers() - 1 {
self.layer_size.pop();
2024-10-14 12:41:32 +00:00
self.db_tx().remove_layer_size(layer);
}
}
pub fn start_transaction(&mut self) {
if self.db_tx.is_none() {
error!("start new tx before commit");
}
self.db_tx = Some(self.db.start_transaction());
}
pub fn commit(&mut self) {
let tx = match self.db_tx.take() {
Some(tx) => tx,
None => {
error!("db_tx is None");
return;
}
};
if let Err(e) = self.db.commit(tx) {
error!("Failed to commit db transaction: {}", e);
2024-10-09 02:36:13 +00:00
}
}
2024-10-14 12:41:32 +00:00
fn db_tx(&mut self) -> &mut dyn NodeTransaction<E> {
(*self.db_tx.as_mut().expect("tx checked")).as_mut()
}
2024-10-09 02:36:13 +00:00
}
pub struct NodeIterator<'a, E: HashElement> {
node_manager: &'a NodeManager<E>,
layer: usize,
start_pos: usize,
end_pos: usize,
}
impl<'a, E: HashElement> Iterator for NodeIterator<'a, E> {
type Item = E;
fn next(&mut self) -> Option<Self::Item> {
if self.start_pos < self.end_pos {
let r = self.node_manager.get_node(self.layer, self.start_pos);
self.start_pos += 1;
r
} else {
None
}
}
2024-10-08 07:40:47 +00:00
}
pub trait NodeDatabase<E: HashElement>: Send + Sync {
fn get_node(&self, layer: usize, pos: usize) -> Result<Option<E>>;
2024-10-14 12:41:32 +00:00
fn get_layer_size(&self, layer: usize) -> Result<Option<usize>>;
fn start_transaction(&self) -> Box<dyn NodeTransaction<E>>;
fn commit(&self, tx: Box<dyn NodeTransaction<E>>) -> Result<()>;
}
pub trait NodeTransaction<E: HashElement>: Send + Sync {
fn save_node(&mut self, layer: usize, pos: usize, node: &E);
2024-10-09 02:36:13 +00:00
/// `nodes` are a list of tuples `(layer, pos, node)`.
2024-10-14 12:41:32 +00:00
fn save_node_list(&mut self, nodes: &[(usize, usize, &E)]);
fn remove_node_list(&mut self, nodes: &[(usize, usize)]);
fn save_layer_size(&mut self, layer: usize, size: usize);
fn remove_layer_size(&mut self, layer: usize);
2024-10-08 07:40:47 +00:00
}
/// A dummy database structure for in-memory merkle tree that will not read/write db.
pub struct EmptyNodeDatabase {}
2024-10-14 12:41:32 +00:00
pub struct EmptyNodeTransaction {}
2024-10-08 07:40:47 +00:00
impl<E: HashElement> NodeDatabase<E> for EmptyNodeDatabase {
fn get_node(&self, _layer: usize, _pos: usize) -> Result<Option<E>> {
Ok(None)
}
2024-10-14 12:41:32 +00:00
fn get_layer_size(&self, _layer: usize) -> Result<Option<usize>> {
Ok(None)
2024-10-08 07:40:47 +00:00
}
2024-10-14 12:41:32 +00:00
fn start_transaction(&self) -> Box<dyn NodeTransaction<E>> {
Box::new(EmptyNodeTransaction {})
2024-10-09 02:36:13 +00:00
}
2024-10-14 12:41:32 +00:00
fn commit(&self, _tx: Box<dyn NodeTransaction<E>>) -> Result<()> {
2024-10-09 02:36:13 +00:00
Ok(())
}
2024-10-08 07:40:47 +00:00
}
2024-10-14 12:41:32 +00:00
impl<E: HashElement> NodeTransaction<E> for EmptyNodeTransaction {
fn save_node(&mut self, _layer: usize, _pos: usize, _node: &E) {}
fn save_node_list(&mut self, _nodes: &[(usize, usize, &E)]) {}
fn remove_node_list(&mut self, _nodes: &[(usize, usize)]) {}
fn save_layer_size(&mut self, _layer: usize, _size: usize) {}
fn remove_layer_size(&mut self, _layer: usize) {}
}