use crate::persistence::Persistable;
use crate::PageId;
use mycelium_command::node::Node;
use std::collections::HashMap;
use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize)]
pub(crate) enum IndexType {
History,
Blob,
}
#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct IndexPage {
i: Vec<PageId>,
t: IndexType,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Page {
#[serde(skip)]
dirty: bool,
id_b: [u8; 16],
id_str: String,
#[serde(skip)]
pub index: HashMap<[u8; 16], usize>,
pub nodes: Vec<Node>,
#[serde(skip)]
max_size: usize,
size: usize,
tag: String,
}
impl Page {
#[allow(dead_code)]
pub fn new(max_size: usize) -> Self {
let id = Uuid::new_v4();
let mut page = Page {
id_b: *id.as_bytes(),
id_str: id.to_string(),
index: HashMap::new(),
nodes: Vec::new(),
size: 0,
tag: String::from("Default"),
max_size,
dirty: false,
};
page.size = std::mem::size_of_val(&page);
page
}
pub fn add(&mut self, node: Node) -> PageId {
let node_id = node.get_id();
self.nodes.push(node);
self.index.insert(node_id, self.nodes.len() - 1);
self.get_id()
}
pub fn build_index(&mut self) {
for (i, n) in self.nodes.iter().enumerate() {
self.index.insert(n.get_id(), i);
}
}
pub fn get_id(&self) -> PageId {
self.id_b
}
pub fn get_nodes(&self) -> &Vec<Node> {
&self.nodes
}
pub fn get_all_nodes(&self) -> &Vec<Node> {
&self.nodes
}
pub fn get_size(&self) -> usize {
let mut total = 0;
for x in &self.nodes {
total += x.get_size();
}
total
}
pub fn get_max_size(&self) -> usize {
self.max_size
}
#[allow(dead_code)]
pub fn get_node_count(&self) -> usize {
self.nodes.len()
}
}
#[test]
fn add_test() {
let mut test_page = Page::new(12);
let node = Node::new([0; 16], vec![0, 0, 0, 0].as_slice());
test_page.add(node);
let node = Node::new([1; 16], vec![1, 1, 1, 1].as_slice());
test_page.add(node);
assert!(test_page.index.len() == 2 && test_page.nodes.len() == 2);
}
impl Persistable for Page {
fn get_id_str(&self) -> &str {
self.id_str.as_str()
}
fn save(&self, path: &std::path::PathBuf) -> std::io::Result<()> {
crate::persistence::persist(self, path)
}
}
pub fn create_page(tag: &str, max_size: usize) -> Page {
let mut page = Page::new(max_size);
page.tag = tag.to_string();
page
}
#[test]
fn test_create_page() {
let page = create_page("test", 100);
assert!(page.tag == "test" && page.max_size == 100);
}