//! Implementation of persistent binary search tree use crndm::alloc::*; use crndm::default::*; use std::convert::TryInto; use std::env; use std::fmt::{Display, Error, Formatter}; type P = crndm::default::BuddyAlloc; type Ptr = Option>; struct BTreeNode { key: i64, slots: [Ptr; 2], value: [u8; 10], } impl BTreeNode { pub fn new(key: i64, value: &str) -> Self { let mut value = value.as_bytes().to_vec(); value.truncate(10); let mut vec = Vec::with_capacity(10); vec.append(&mut value); while vec.len() < 10 { vec.push(0); } Self { key, slots: [None, None], value: vec.as_slice().try_into().unwrap(), } } } impl Display for BTreeNode { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { write!( f, "{} {}", self.key, String::from_utf8(self.value.to_vec()).unwrap() ) } } struct BTree { root: Ptr, } impl RootObj

for BTree { fn init(_j: &Journal) -> Self { Self { root: None } } } impl BTree { pub fn insert(&self, key: i64, value: &str) { let mut dst = &self.root; while let Some(node) = dst { dst = &node.slots[if key > node.key { 1 } else { 0 }]; } let _ = Pbox::initialize(dst, BTreeNode::new(key, value)); } pub fn find(&self, key: i64) -> Option { let mut curr = &self.root; while let Some(node) = curr { if node.key == key { return Some(String::from_utf8(node.value.to_vec()).unwrap()); } else { curr = &node.slots[if key > node.key { 1 } else { 0 }]; } } None } fn foreach ()>(node: &Ptr, f: F) { if let Some(node) = node { Self::foreach(&node.slots[0], f); f(node); Self::foreach(&node.slots[1], f); } } pub fn print(&self) { Self::foreach(&self.root, |p| { println!("{}", p); }); } } fn main() { let args: Vec = env::args().collect(); if args.len() < 3 { println!( "usage: {} file-name [p|r|s|i|f] [key/count] [value]", args[0] ); } else { let root = P::open::(&args[1], O_CFNE | O_1GB).unwrap(); let op = args[2].chars().next().unwrap(); match op { 'p' => root.print(), 'i' => { let key: i64 = args[3].parse().unwrap(); let value = &args[4]; root.insert(key, value); } 'f' => { let key: i64 = args[3].parse().unwrap(); if let Some(value) = root.find(key) { println!("{}", value); } else { println!("not found\n"); } } 's' => { let cnt: i64 = args[3].parse().unwrap(); for i in 1..cnt { root.insert(i, "test"); } } 'r' => { let cnt: i64 = args[3].parse().unwrap(); for i in 1..cnt { let _ = root.find(i); } } _ => { println!("Unknown command `{}`", args[2]); } } } }