pub use atom_file::Data;
use std::hash::Hash;
use std::sync::Arc;
pub trait SmallFixed {
fn size() -> usize;
fn load(bytes: &[u8]) -> Self;
fn save(&self, bytes: &mut [u8]);
}
pub trait Key<T>: Hash
where
T: SmallFixed,
{
fn ok(&self, addr: &T, ps: &mut PageSet) -> Option<Value>;
}
pub mod pageset;
pub use pageset::*;
pub mod hashmap;
pub use hashmap::*;
pub mod table;
pub use table::*;
pub mod varval;
pub use varval::*;
pub mod sys;
pub use sys::*;
pub mod datatype;
pub use datatype::*;
pub mod value;
pub use value::*;
mod pagetree;
use pagetree::*;
mod treevec;
use treevec::*;
mod bucket;
const PAGE_SIZE: u64 = 4612;
use pstd::localalloc::Local;
pub type LString = pstd::StringA<Local>;
pub type LVec<T> = pstd::VecA<T, Local>;
pub type LBox<T> = pstd::BoxA<T, Local>;
#[test]
fn test_main() {
use page_store::*;
let limits = Limits::default();
let file = atom_file::MultiFileStorage::new("test.db");
let upd = atom_file::FastFileStorage::new("test.upd");
let af = atom_file::AtomicFile::new_with_limits(file, upd, &limits.af_lim);
let ps = BlockPageStg::new(af, &limits);
let is_new = ps.is_new();
let spd = SharedPagedData::new_from_ps(ps);
println!("max page size={}", spd.psi.max_size_page());
let mut ps = PageSet::new(spd.new_writer());
if false {
let (root, len) = if is_new { (ps.new_page(), 0) } else { (3, 410) };
test_tv(root, len, &mut ps);
}
if false {
test_table(&mut ps);
}
if false {
test_varval(&mut ps);
}
test_cust(&mut ps);
spd.shutdown();
}
#[cfg(test)]
fn tos(s: &[u8]) -> &str {
str::from_utf8(s).unwrap()
}
#[cfg(test)]
#[derive(Hash)] struct CustKey<'a> {
rid: i64,
cdt: &'a DataType,
}
#[cfg(test)]
impl<'a> Key<VarValAddr> for CustKey<'a> {
fn ok(&self, addr: &VarValAddr, ps: &mut PageSet) -> Option<Value> {
let mut cr = addr.get(&self.cdt, ps);
let rid = cr.list()[0].int();
if rid == self.rid
{
return Some(cr);
}
None
}
}
#[cfg(test)]
#[derive(Hash)] struct CustEmailKey<'a> {
email: &'a str,
cdt: &'a DataType,
}
#[cfg(test)]
impl<'a> Key<VarValAddr> for CustEmailKey<'a> {
fn ok(&self, addr: &VarValAddr, ps: &mut PageSet) -> Option<Value> {
let dt = DataType::IList;
let mut list = addr.get(&dt, ps);
let rid = list.ilist()[0];
let key = CustKey{ rid, cdt: self.cdt };
let hms = ps.cust_hashmap;
let mut hm = HashMap::restore(hms, ps);
let mut cr = hm.get(&key).unwrap();
let email = cr.list()[2].string();
if *self.email == **email
{
return Some(list);
}
None
}
}
#[cfg(test)]
fn init(ps: &mut PageSet) {
let hm = HashMap::<VarValAddr>::new(ps, 1);
ps.cust_hashmap = hm.save();
let hm = HashMap::<VarValAddr>::new(ps, 1);
ps.cust_by_email = hm.save();
}
#[cfg(test)]
fn cust_dt() -> DataType {
use pstd::veca;
DataType::Struct(veca![
(LString::from("Id"), DataType::Int),
(LString::from("Name"), DataType::String),
(LString::from("Email"), DataType::String),
(LString::from("Postal"), DataType::String)
])
}
#[cfg(test)]
fn make_cust(ps: &mut PageSet, cdt: &DataType, rid: i64, name: &str, email: &str, postal: &str) {
use pstd::veca;
let mut cr = Value::List(veca![
Value::Int(rid),
Value::String(LString::from(name)),
Value::String(LString::from(email)),
Value::String(LString::from(postal)),
]);
println!("make_cust cr={:?}", &cr);
let addr = VarValAddr::new(cdt, &mut cr, ps);
{
let key = CustKey{rid, cdt};
let mut hm = HashMap::restore(ps.cust_hashmap, ps);
hm.insert(&key, addr);
if hm.root_changed() {
ps.cust_hashmap = hm.save();
}
}
let emkey = CustEmailKey { email, cdt };
let list = {
let mut hm = HashMap::restore(ps.cust_by_email, ps);
let list = hm.remove(&emkey);
if hm.root_changed() {
ps.cust_by_email = hm.save();
}
list
};
let dt2 = DataType::IList;
let addr = if let Some(mut list) = list {
list.ilist().push(rid);
addr.update(&dt2, &mut list, ps)
} else {
let mut list = Value::IList(veca![rid]);
VarValAddr::new(&dt2, &mut list, ps)
};
let mut hm = HashMap::restore(ps.cust_by_email, ps);
hm.insert(&emkey, addr);
if hm.root_changed() {
ps.cust_by_email = hm.save();
}
}
#[cfg(test)]
fn list_cust(ps: &mut PageSet, cdt: &DataType, email: &str) {
let key = CustEmailKey { email, cdt };
let mut hm = HashMap::restore(ps.cust_by_email, ps);
if let Some(mut list) = hm.get(&key) {
println!("List of cust ids for {} = {:?}", email, list.ilist());
} else {
println!("No cust ids found for email {}", email);
}
}
#[cfg(test)]
fn test_cust(ps: &mut PageSet) {
init(ps);
let cdt = cust_dt();
make_cust(
ps,
&cdt,
99,
"George Barwood",
"george@gmail.com",
"33 Sandpipe Close, GL2 4LZ",
);
make_cust(
ps,
&cdt,
100,
"George Barwood",
"george@gmail.com",
"33 Sandpipe Close, GL2 4LZ",
);
make_cust(
ps,
&cdt,
101,
"George Barwood",
"george@gmail.com",
"33 Sandpipe Close, GL2 4LZ",
);
make_cust(
ps,
&cdt,
102,
"Marilyn Barwood",
"maz.barwood@gmail.com",
"33 Sandpipe Close, GL2 4LZ",
);
list_cust(ps, &cdt, "george@gmail.com");
list_cust(ps, &cdt, "maz.barwood@gmail.com");
list_cust(ps, &cdt, "mary@gmail.com");
}