use crate::{Arc, Data, DataType, BuckMap, BuckMapInfo, Rc, make_obj_dt};
use crate::VarValAddr;
use page_store::*;
pub struct PData {
pub data: Data,
pub pnum: u64,
pub changed: bool,
can_drop: bool,
}
impl PData {
pub fn new(pnum: u64, data: Data, changed: bool) -> Self {
Self {
pnum,
data,
changed,
can_drop: false,
}
}
pub fn take_data(&mut self) -> Data {
std::mem::take(&mut self.data)
}
pub fn make_mut(&mut self) -> &mut Vec<u8> {
Arc::make_mut(&mut self.data)
}
}
impl Drop for PData {
fn drop(&mut self) {
if !self.can_drop {
panic!();
}
}
}
pub struct PageSet {
wapd: AccessPagedData,
clean: HashMap<u64, Data>,
changed: HashMap<u64, Data>,
pub vvs: (u64, u64),
pub obj_dt: Rc<DataType>,
pub next_obj_id: i64,
pub obj_map: BuckMapInfo,
pub obj_by_name: BuckMapInfo,
pub table_datatype_map: BuckMapInfo,
}
impl PageSet {
pub fn new(wapd: AccessPagedData) -> Self {
let root1 = wapd.alloc_page() + 1;
let mut ps = Self {
wapd,
clean: HashMap::default(),
changed: HashMap::default(),
vvs: (root1, 0),
next_obj_id: 0,
obj_map: BuckMapInfo::default(),
obj_by_name: BuckMapInfo::default(),
table_datatype_map: BuckMapInfo::default(),
obj_dt: Rc::new(make_obj_dt()),
};
ps.obj_map = BuckMap::<VarValAddr>::new(1, &mut ps).save();
ps.obj_by_name = BuckMap::<VarValAddr>::new(1, &mut ps).save();
ps.table_datatype_map = BuckMap::<VarValAddr>::new(1, &mut ps).save();
ps
}
pub fn new_page(&self) -> u64 {
self.wapd.alloc_page() + 1 }
pub fn free_page(&mut self, pnum: u64) {
self.clean.remove(&pnum);
self.changed.remove(&pnum);
self.wapd.free_page(pnum - 1);
}
pub fn load(&mut self, pnum: u64) -> PData {
if let Some(data) = self.clean.remove(&pnum) {
PData::new(pnum, data, false)
} else if let Some(data) = self.changed.remove(&pnum) {
PData::new(pnum, data, true)
} else {
let data = self.wapd.get_data(pnum - 1);
PData::new(pnum, data, false)
}
}
pub fn note(&mut self, mut pd: PData) {
if pd.changed {
self.changed.insert(pd.pnum, pd.take_data());
} else {
self.clean.insert(pd.pnum, pd.take_data());
}
pd.can_drop = true;
}
pub fn save(&mut self) {
for (pnum, data) in self.changed.drain() {
println!("Saving data pnum={} len={}", pnum, data.len());
self.wapd.set_data(pnum - 1, data);
}
self.wapd.save(SaveOp::Save);
}
}