use std::ops::RangeInclusive;
use std::sync::Arc;
use async_trait::async_trait;
use d_engine_proto::common::Entry;
use d_engine_proto::common::LogId;
#[cfg(any(test, feature = "__test_support"))]
use mockall::automock;
use crate::Error;
use crate::HardState;
pub trait StorageEngine: Send + Sync + 'static {
type LogStore: LogStore;
type MetaStore: MetaStore;
fn log_store(&self) -> Arc<Self::LogStore>;
fn meta_store(&self) -> Arc<Self::MetaStore>;
}
#[cfg_attr(any(test, feature = "__test_support"), automock)]
#[async_trait]
pub trait LogStore: Send + Sync + 'static {
async fn persist_entries(
&self,
entries: Vec<Entry>,
) -> Result<(), Error>;
async fn entry(
&self,
index: u64,
) -> Result<Option<Entry>, Error>;
fn get_entries(
&self,
range: RangeInclusive<u64>,
) -> Result<Vec<Entry>, Error>;
async fn purge(
&self,
cutoff_index: LogId,
) -> Result<(), Error>;
async fn truncate(
&self,
from_index: u64,
) -> Result<(), Error>;
async fn replace_range(
&self,
from_index: u64,
new_entries: Vec<Entry>,
) -> Result<(), Error> {
self.truncate(from_index).await?;
if !new_entries.is_empty() {
self.persist_entries(new_entries).await?;
}
Ok(())
}
fn is_write_durable(&self) -> bool;
fn flush(&self) -> Result<(), Error> {
Ok(()) }
async fn flush_async(&self) -> Result<(), Error> {
Ok(()) }
async fn reset(&self) -> Result<(), Error>;
fn last_index(&self) -> u64;
fn load_purge_boundary(&self) -> Result<Option<LogId>, Error> {
Ok(None) }
}
#[cfg_attr(any(test, feature = "__test_support"), automock)]
#[async_trait]
pub trait MetaStore: Send + Sync + 'static {
fn save_hard_state(
&self,
state: &HardState,
) -> Result<(), Error>;
fn load_hard_state(&self) -> Result<Option<HardState>, Error>;
fn flush(&self) -> Result<(), Error> {
Ok(()) }
async fn flush_async(&self) -> Result<(), Error> {
Ok(()) }
}