use std::path::Path;
use linkrs_core::StorageResult;
use super::super::core::VertexTable;
impl VertexTable {
pub fn apply_delta_pages(&mut self, shard_dir: &Path) -> StorageResult<()> {
let delta_dir = shard_dir.join("columns_pages");
if !delta_dir.exists() {
return Ok(());
}
let mut applied: Vec<(String, usize)> = Vec::new();
for entry in std::fs::read_dir(&delta_dir)? {
let entry = entry?;
let path = entry.path();
if path.extension().and_then(|e| e.to_str()) != Some("page") {
continue;
}
let bytes = match std::fs::read(&path) {
Ok(bytes) => bytes,
Err(e) => {
let (col_name, _) = match path
.file_stem()
.and_then(|n| n.to_str())
.and_then(|stem| stem.rsplit_once('_'))
{
Some((name, _)) => (name.to_string(), ()),
None => {
return Err(linkrs_core::StorageError::deserialize_error(format!(
"bad delta page name {}",
path.display()
)));
}
};
let reason = format!("delta page unreadable at {}: {}", path.display(), e);
log::warn!("column {} unavailable: {}", col_name, reason);
self.columns.mark_column_unavailable(&col_name, reason);
continue;
}
};
let (col_name, page_id) = match path
.file_stem()
.and_then(|n| n.to_str())
.and_then(|stem| stem.rsplit_once('_'))
{
Some((name, page)) => match page.parse::<usize>() {
Ok(id) => (name.to_string(), id),
Err(_) => {
return Err(linkrs_core::StorageError::deserialize_error(format!(
"bad delta page name {}",
path.display()
)));
}
},
None => {
return Err(linkrs_core::StorageError::deserialize_error(format!(
"bad delta page name {}",
path.display()
)));
}
};
let Some(col) = self.columns.get_column(&col_name) else {
return Err(linkrs_core::StorageError::deserialize_error(format!(
"delta page {} targets unknown column {}",
path.display(),
col_name
)));
};
if let Err(e) = col.deserialize_page(&bytes) {
let reason = format!(
"corrupt delta page {} for column {}: {}",
path.display(),
col_name,
e
);
log::warn!("column {} unavailable: {}", col_name, reason);
self.columns.mark_column_unavailable(&col_name, reason);
continue;
}
applied.push((col_name, page_id));
}
self.columns.clear_pages(&applied);
Ok(())
}
}