use crate::*;
pub struct VarVal {
pub t: Table,
}
impl VarVal {
pub fn store(&mut self, user_data: &[u8], ps: &mut PageSet) -> u64 {
let mut todo: usize = user_data.len();
let id = self.t.next_id;
let mut done: usize = 0;
while todo > 0 {
let mut amount = self.t.record_size;
if amount > todo {
amount = todo
};
self.t.append(&user_data[done..done + amount], ps);
done += amount;
todo -= amount;
}
id
}
pub fn get(&mut self, mut id: u64, len: usize, user_data: &mut [u8], ps: &mut PageSet) {
let mut done = 0;
let mut todo = len;
while todo > 0 {
let mut amount = self.t.record_size;
if amount > todo {
amount = todo
};
self.t.read(id, &mut user_data[done..done + amount], ps);
done += amount;
todo -= amount;
id += 1;
}
}
pub fn delete(&mut self, id: u64, len: usize, ps: &mut PageSet) {
let count = len.div_ceil(self.t.record_size);
self.t.delete_range(id, count, ps);
}
pub fn update(
&mut self,
old_id: u64,
old_len: usize,
user_data: &[u8],
ps: &mut PageSet,
) -> u64 {
let old_count = old_len.div_ceil(self.t.record_size);
let new_count = user_data.len().div_ceil(self.t.record_size);
if old_count == new_count {
let mut done = 0;
let mut todo = user_data.len();
let mut id = old_id;
while todo > 0 {
let mut amount = self.t.record_size;
if amount > todo {
amount = todo;
}
self.t.update(id, &user_data[done..done + amount], ps);
done += amount;
todo -= amount;
id += 1;
}
old_id
} else {
self.t.delete_range(old_id, old_count, ps);
self.store(user_data, ps)
}
}
}
#[cfg(test)]
pub fn test_varval(ps: &mut PageSet) {
let rpp = 64;
let t = Table {
next_id: 0,
root: ps.new_page(),
len: 0,
record_size: ((PAGE_SIZE - 8) / rpp) as usize,
rpp,
};
let mut vv = VarVal { t };
let mut ids = Vec::new();
let d1 = b"Hello there George";
let d2 = b"Tuesday is lovely, so is Wednesday";
for _ in 0..1_000_000 {
let id = vv.store(d1, ps);
ids.push(id);
}
let mut buf = vec![0; d1.len()];
for id in &ids {
vv.get(*id, d1.len(), &mut buf, ps);
assert_eq!(buf, d1);
}
let mut nids = Vec::new();
for id in &ids {
let nid = vv.update(*id, d1.len(), d2, ps);
nids.push(nid);
}
let mut buf = vec![0; d2.len()];
for id in &nids {
vv.get(*id, d2.len(), &mut buf, ps);
assert_eq!(buf, d2);
}
println!("t.len (page details)={}", vv.t.len);
}