use crate::bplustree::{NodeId, NodeView};
use crate::codec::CodecError;
use crate::layout::PAGE_SIZE;
use crate::storage::epoch::EpochManager;
use std::path::Path;
pub mod epoch;
pub mod file_page_storage;
pub mod metadata_manager;
pub mod paged_node_storage;
use thiserror::Error;
#[non_exhaustive]
#[derive(Debug, Error)]
pub enum StorageError {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Codec(#[from] CodecError),
#[error("page {pid} not found")]
NotFound { pid: NodeId },
#[error("storage invariant violated: {0}")]
Invariant(&'static str),
}
pub trait HasEpoch {
fn epoch_mgr(&self) -> &std::sync::Arc<EpochManager>;
}
pub trait PageStorage {
fn open<P: AsRef<Path>>(path: P) -> Result<Self, std::io::Error>
where
Self: Sized;
fn read_page(&self, page_id: u64, target: &mut [u8; PAGE_SIZE]) -> Result<(), std::io::Error>;
fn write_page(&self, data: &[u8]) -> Result<u64, std::io::Error>;
fn write_page_at_offset(&self, offset: u64, data: &[u8]) -> Result<u64, std::io::Error>;
fn flush(&self) -> Result<(), std::io::Error>;
fn allocate_page(&self) -> Result<u64, std::io::Error>;
fn free_page(&self, page_id: u64) -> Result<(), std::io::Error>;
fn close(&self) -> Result<(), std::io::Error>;
fn set_next_page_id(&self, next_page_id: u64) -> Result<(), std::io::Error>;
fn set_freelist(&self, freed_pages: Vec<u64>) -> Result<(), std::io::Error>;
fn get_next_page_id(&self) -> u64;
fn get_freelist(&self) -> Vec<u64>;
}
pub trait NodeStorage: Send + Sync + 'static {
fn read_node_view(&self, id: u64) -> Result<Option<NodeView>, StorageError>;
fn write_node_view(&self, node_view: &NodeView) -> Result<u64, StorageError>;
fn write_node_view_at_offset(
&self,
node_view: &NodeView,
offset: u64,
) -> Result<u64, StorageError>;
fn flush(&self) -> Result<(), StorageError>;
fn free_node(&self, id: u64) -> Result<(), StorageError>;
}