use crate::format::BlockDecoder;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct AppendOptions {
pub durable: bool,
}
impl Default for AppendOptions {
fn default() -> Self {
Self { durable: true }
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ReadOrder {
Forward,
Backward,
}
pub trait AppendLogVisitor {
fn visit(&mut self, block: &[u8], context: BlockVisitContext) -> pi_result::Result<bool>;
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct BlockVisitContext {
pub is_first_in_structure: bool,
pub is_last_in_structure: bool,
}
pub trait Layout: Send + Sync {
type StructureId: Clone + Ord + Send + Sync + 'static;
type Name: Clone + Send + Sync + 'static;
fn segment_name(&self, structure_id: &Self::StructureId) -> Self::Name;
fn archive_name(&self, structure_id: &Self::StructureId) -> Self::Name;
fn parse_segment_name(&self, name: &Self::Name) -> Option<Self::StructureId>;
fn parse_archive_name(&self, name: &Self::Name) -> Option<Self::StructureId>;
}
pub trait AppendLog: Send + Sync {
type Closed: Clone + Send + Sync + 'static;
async fn append<'a, B>(&'a self, block: B, options: AppendOptions) -> pi_result::Result<u64>
where
B: pi_async_fs::DetachableWriteBuffer + Send + 'a,
B::Detached: Send,
B::Recovery: Send + 'a;
async fn append_stream<'a, S, B>(
&'a self,
stream: S,
options: AppendOptions,
) -> pi_result::Result<u64>
where
S: futures_core::Stream<Item = pi_result::Result<B>> + Send + 'a,
B: pi_async_fs::DetachableWriteBuffer + Send + 'a,
B::Detached: Send,
B::Recovery: Send + 'a;
async fn rotate(&self) -> pi_result::Result<Option<Self::Closed>>;
async fn archive(&self, closed: Self::Closed) -> pi_result::Result<()>;
}
pub struct BuildResult<S>
where
S: AppendLog,
{
pub storage: S,
pub recovered_closed: Vec<S::Closed>,
}
pub trait AppendLogBuilder: Send {
type Storage: AppendLog;
async fn build<D, V>(
self,
decoder: &D,
order: ReadOrder,
visitor: &mut V,
) -> pi_result::Result<BuildResult<Self::Storage>>
where
D: BlockDecoder + Send + Sync,
V: AppendLogVisitor + Send;
}