use rand::Rng;
use crate::storage;
macro_rules! open_file {
($name: expr) => {
std::fs::File::options().read(true).write(true).create(true).open($name).unwrap()
};
}
fn init() {
std::fs::remove_dir_all("./local").unwrap();
std::fs::create_dir("./local").unwrap();
std::env::set_var("RUST_BACKTRACE", "1");
}
binbuf::fixed! {
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct TestEntry1 {
#[lens(buf_idx)]
idx: u64,
#[lens(buf_opt)]
opt: Option<bool>,
}
buf! { pub struct TestEntry1Buf<P>(TestEntry1, P); }
impl I for TestEntry1 {
type Buf<P> = TestEntry1Buf<P>;
}
impl Code for TestEntry1 {}
}
pub fn fixed_test1() {
init();
let mut db = unsafe {
storage::Fixed::create(
open_file!("./local/fixed1"),
10
)
}.unwrap();
let entry = TestEntry1 {
idx: 5,
opt: Some(false),
};
let id = db.add(&entry).unwrap();
let output_entry = db.get(id);
println!("{:?}", &output_entry);
assert_eq!(entry, output_entry);
db.remove_last().unwrap();
assert_eq!(db.len(), 0);
let entry = TestEntry1 {
idx: 2077,
opt: None,
};
let id = db.add(&entry).unwrap();
let output_entry = db.get(id);
println!("{:?}", &output_entry);
assert_eq!(entry, output_entry);
assert_eq!(db.len(), 1);
}
pub fn dynamic_test1() {
init();
let mut db = unsafe {
storage::Dynamic::<String>::create(
storage::Fixed::create(
open_file!("./local/dynamic1_free_locations"),
10,
).unwrap(),
open_file!("./local/dynamic1"),
10,
)
}.unwrap();
let entry = "Hello from bindb!".to_string();
let id = db.add(&entry).unwrap();
let id1 = id;
let out = unsafe { db.get(id) };
println!("{}", &out);
assert_eq!(&entry, &out);
let entry = "What is up everyone? I'm feeling good today. How are you?".to_string();
let id = db.add(&entry).unwrap();
let out = unsafe { db.get(id) };
println!("{}", &out);
assert_eq!(&entry, &out);
unsafe { db.remove(id1) }.unwrap();
let entry = "Hello again!".to_string();
let id = db.add(&entry).unwrap();
let out = unsafe { db.get(id1) };
println!("{}", &out);
assert_eq!(&entry, &out);
}
pub fn indexed_dynamic_test1() {
init();
let mut db = unsafe {
storage::IndexedDynamic::<String>::open(
storage::Dynamic::create(
storage::Fixed::create(
open_file!("./local/indexed_dynamic1_free_locations"),
10,
).unwrap(),
open_file!("./local/indexed_dynamic1"),
10,
).unwrap(),
storage::Fixed::create(
open_file!("./local/indexed_dynamic1_indices"),
10
).unwrap(),
storage::Fixed::create(
open_file!("./local/indexed_dynamic1_free_ids"),
10
).unwrap(),
).unwrap()
};
let entry = "What is up everyone? I'm feeling good today. How are you?".to_string();
let id = db.add(&entry).unwrap();
let out = unsafe { db.get(id) };
println!("{}", &out);
assert_eq!(&entry, &out);
unsafe { db.remove(id).unwrap() };
}
#[test]
pub fn indexed_dynamic_test2() {
init();
let mut db = unsafe {
storage::IndexedDynamic::<String>::open(
storage::Dynamic::create(
storage::Fixed::create(
open_file!("./local/indexed_dynamic1_free_locations"),
10,
).unwrap(),
open_file!("./local/indexed_dynamic1"),
10,
).unwrap(),
storage::Fixed::create(
open_file!("./local/indexed_dynamic1_indices"),
10
).unwrap(),
storage::Fixed::create(
open_file!("./local/indexed_dynamic1_free_ids"),
10
).unwrap(),
).unwrap()
};
for i in 0 .. 10 {
db.add(&"Some value!".to_string()).unwrap();
}
for i in 0 .. 10 {
unsafe { db.remove(i) }.unwrap();
}
let mut ids = Vec::new();
for i in 0 .. 10 {
ids.push(db.add(&"Some value!".to_string()).unwrap());
}
for id in ids {
assert_eq!(db.get(id), "Some value!".to_string());
}
}
pub fn single_test1() {
init();
let entry = "What's up!?".to_string();
let mut db = unsafe {
storage::Single::create(open_file!("./local/single1"), &entry).unwrap()
};
assert_eq!(&db.get(), &entry);
let entry = "New value...".to_string();
db.set(&entry).unwrap();
assert_eq!(&db.get(), &entry);
}
pub fn binary_tree_test1() {
use binbuf::impls::{ArbNum, arb_num};
init();
let entry = "What's up!?".to_string();
let mut db = unsafe {
storage::BinaryTree::<ArbNum<4, u64>, i32, TestEntry1>::create(
storage::Fixed::create(open_file!("./local/binary_tree1_nodes"), 10).unwrap(),
storage::Fixed::create(open_file!("./local/binary_tree_free_ids"), 10).unwrap(),
open_file!("./local/binary_tree1_header")
).unwrap()
};
let entry = TestEntry1 {
idx: 999,
opt: Some(true),
};
db.add(&584, &entry).unwrap();
assert_eq!(db.get(&555), None);
assert_eq!(db.get(&584), Some(entry.clone()));
db.add(&103, &entry).unwrap();
db.remove(&584);
assert_eq!(db.get(&584), None);
}
pub fn binary_tree_test2() {
use binbuf::impls::{ArbNum, arb_num};
init();
let entry = "What's up!?".to_string();
let mut db = unsafe {
storage::BinaryTree::<ArbNum<4, u64>, u64, TestEntry1>::create(
storage::Fixed::create(open_file!("./local/binary_tree1_nodes"), 10).unwrap(),
storage::Fixed::create(open_file!("./local/binary_tree_free_ids"), 10).unwrap(),
open_file!("./local/binary_tree1_header")
).unwrap()
};
let mut rng = rand::thread_rng();
let mut keys = Vec::new();
for i in 0 .. 100 {
let key = rng.r#gen::<u64>();
if !db.add(&key, &TestEntry1 { idx: 5, opt: Some(false) }).unwrap() {
keys.push(key);
}
}
for key in &keys {
assert_eq!(db.get(key).unwrap(), TestEntry1 { idx: 5, opt: Some(false) });
}
for key in &keys {
if db.remove(key).unwrap() {
panic!("Key {key} doesn't exist! Failed to remove!");
}
}
}