pub mod persistence;
pub use persistence::SledNodeRecordStore;
use crate::error::StorageError;
use crate::tree::node::MerkleNode;
use crate::tree::Tree;
use crate::types::{Hash, NodeID};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NodeType {
File { size: u64, content_hash: [u8; 32] },
Directory,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeRecord {
pub node_id: NodeID,
pub path: PathBuf,
pub node_type: NodeType,
pub children: Vec<NodeID>,
pub parent: Option<NodeID>,
pub frame_set_root: Option<Hash>,
pub metadata: HashMap<String, String>,
pub tombstoned_at: Option<u64>,
}
pub trait NodeRecordStore {
fn get(&self, node_id: &NodeID) -> Result<Option<NodeRecord>, StorageError>;
fn put(&self, record: &NodeRecord) -> Result<(), StorageError>;
fn find_by_path(&self, path: &Path) -> Result<Option<NodeRecord>, StorageError>;
fn list_all(&self) -> Result<Vec<NodeRecord>, StorageError>;
fn list_active(&self) -> Result<Vec<NodeRecord>, StorageError>;
fn get_by_path(&self, path: &Path) -> Result<Option<NodeRecord>, StorageError>;
fn tombstone(&self, node_id: &NodeID) -> Result<NodeRecord, StorageError>;
fn restore(&self, node_id: &NodeID) -> Result<NodeRecord, StorageError>;
fn purge(&self, node_id: &NodeID, cutoff: u64) -> Result<(), StorageError>;
fn list_tombstoned(&self, older_than: Option<u64>) -> Result<Vec<NodeID>, StorageError>;
fn flush(&self) -> Result<(), StorageError> {
Ok(())
}
}
impl NodeRecord {
pub fn from_merkle_node(
node_id: NodeID,
node: &MerkleNode,
tree: &Tree,
) -> Result<Self, StorageError> {
match node {
MerkleNode::File(file) => {
Ok(NodeRecord {
node_id,
path: file.path.clone(),
node_type: NodeType::File {
size: file.size,
content_hash: file.content_hash,
},
children: vec![], parent: tree.find_parent(&node_id),
frame_set_root: None,
metadata: file
.metadata
.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect(),
tombstoned_at: None,
})
}
MerkleNode::Directory(dir) => {
let children: Vec<NodeID> =
dir.children.iter().map(|(_, node_id)| *node_id).collect();
Ok(NodeRecord {
node_id,
path: dir.path.clone(),
node_type: NodeType::Directory,
children,
parent: tree.find_parent(&node_id),
frame_set_root: None,
metadata: dir
.metadata
.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect(),
tombstoned_at: None,
})
}
}
}
pub fn populate_store_from_tree(
store: &dyn NodeRecordStore,
tree: &Tree,
) -> Result<(), StorageError> {
for (node_id, node) in &tree.nodes {
let record = Self::from_merkle_node(*node_id, node, tree)?;
store.put(&record)?;
}
Ok(())
}
}