use yo_kv::restore::{Fault, Item, Load};
use super::{DATABASES, Server};
#[derive(Debug, Default, Clone, Copy)]
pub struct Loaded {
pub version: u16,
pub keys: [usize; DATABASES],
pub expired: usize,
pub libraries: usize,
}
impl Loaded {
#[must_use]
pub fn total(&self) -> usize {
self.keys.iter().sum()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Refused {
Fault(Fault),
Database(usize),
}
impl core::fmt::Display for Refused {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Refused::Fault(fault) => write!(f, "{fault}"),
Refused::Database(db) => write!(
f,
"the file has a key in database {db} and there are {DATABASES}"
),
}
}
}
impl Server {
pub fn load_image(&self, image: &[u8], flush: bool) -> Result<Loaded, Refused> {
let bands = self.dbs[0].hold_stripe(0).bands();
let mut load =
Load::open(image, bands.limits(), self.clock.now_ms()).map_err(Refused::Fault)?;
let mut done = Loaded {
version: load.version(),
..Loaded::default()
};
if flush {
for db in &self.dbs {
db.clear();
}
}
for item in load.by_ref() {
match item {
Ok(Item::Key { db, key, record }) => {
let Some(into) = self.dbs.get(db) else {
return Err(Refused::Database(db));
};
into.hold(&key).import(&key, record);
done.keys[db] += 1;
}
Ok(Item::Library(_)) => done.libraries += 1,
Ok(Item::Aux { .. }) => {}
Err(fault) => return Err(Refused::Fault(fault)),
}
}
done.expired = load.expired();
self.persist.note_load(&done);
Ok(done)
}
}