use crate::{Data, LRc};
use std::cell::RefCell;
use page_store::*;
pub struct PageSet {
wapd: AccessPagedData,
pages: HashMap<u64, PData>,
}
impl PageSet {
pub fn new(wapd: AccessPagedData) -> Self {
Self {
wapd,
pages: 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 new_pdata(&mut self, pnum: u64, data: Data) {
let pdata = LRc::new(RefCell::new(PDataInner {
data,
changed: true,
}));
self.pages.insert(pnum, pdata);
}
pub fn free_page(&mut self, pnum: u64) {
self.pages.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(pdata) = self.pages.get(&pnum) {
pdata.clone()
} else {
let data = self.wapd.get_data(pnum - 1);
let pdata = LRc::new(RefCell::new(PDataInner {
data,
changed: false,
}));
self.pages.insert(pnum, pdata.clone());
pdata
}
}
pub fn save(&mut self) {
for (pnum, data) in self.pages.drain() {
if data.borrow().changed {
self.wapd.set_data(pnum - 1, take_data(&data));
}
}
self.wapd.save(SaveOp::Save);
}
}
pub type PData = LRc<RefCell<PDataInner>>;
#[derive(Default)]
pub struct PDataInner {
pub data: Data,
changed: bool,
}
pub fn set_changed(pdata: &PData) {
pdata.borrow_mut().changed = true;
}
pub fn take_data(pdata: &PData) -> Data {
std::mem::take(&mut pdata.borrow_mut().data)
}
pub fn set_data(pdata: &PData, data: Data) {
pdata.borrow_mut().data = data;
}
pub fn pdata_default() -> PData {
LRc::new(RefCell::new(PDataInner::default()))
}