use crate::{Arc, Data };
use page_store::*;
pub struct PageSet {
wapd: AccessPagedData,
clean: HashMap<u64, Data>,
changed: HashMap<u64, Data>,
}
impl PageSet {
pub fn new(wapd: AccessPagedData) -> Self {
Self {
wapd,
clean: HashMap::default(),
changed: HashMap::default(),
}
}
pub fn compute_size(&self, size: usize) -> usize {
let psi = &self.wapd.spd.psi;
if size > psi.max_size_page() {
return 0;
}
let ix = psi.index(size);
psi.size(ix)
}
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 pnum == 0 {
PData::default() } else 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.pnum == 0 {
} else if pd.changed {
self.changed.insert(pd.pnum, pd.take_data());
} else {
self.clean.insert(pd.pnum, pd.take_data());
}
pd.no_drop = false;
}
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);
}
}
#[derive(Default)]
pub struct PData {
pub data: Data,
pnum: u64,
pub changed: bool,
no_drop: bool,
}
impl PData {
pub fn new(pnum: u64, data: Data, changed: bool) -> Self {
Self {
pnum,
data,
changed,
no_drop: true,
}
}
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) {
assert!(!self.no_drop); }
}