use std::path::Path;
use iqdb_index::IndexCore;
use crate::error::{PersistError, Result};
use crate::wal::{self, WalRecord};
pub(crate) fn replay<I: IndexCore>(snapshot: &Path, index: &mut I) -> Result<usize> {
let path = wal::wal_path(snapshot);
let bytes = match std::fs::read(&path) {
Ok(b) => b,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(0),
Err(source) => return Err(PersistError::Io { path, source }),
};
let records = wal::parse_records(&bytes)?;
let mut applied = 0usize;
for record in records {
match record {
WalRecord::Insert { id, vector, meta } => {
if vector.len() != index.dim() {
return Err(PersistError::InvalidPayload {
reason: "WAL insert vector dimension disagrees with the index",
});
}
index.insert(id, vector, meta)?;
}
WalRecord::Delete { id } => {
index.delete(&id)?;
}
}
applied += 1;
}
Ok(applied)
}