use std::sync::Arc;
use bytes::Bytes;
use crate::{
backend::{FileType, ReadBackend, WriteBackend},
error::RusticResult,
id::Id,
};
#[derive(Clone, Debug)]
pub struct HotColdBackend {
be: Arc<dyn WriteBackend>,
be_hot: Arc<dyn WriteBackend>,
}
impl HotColdBackend {
pub fn new<BE: WriteBackend>(be: BE, hot_be: BE) -> Self {
Self {
be: Arc::new(be),
be_hot: Arc::new(hot_be),
}
}
}
impl ReadBackend for HotColdBackend {
fn location(&self) -> String {
self.be.location()
}
fn list_with_size(&self, tpe: FileType) -> RusticResult<Vec<(Id, u32)>> {
self.be.list_with_size(tpe)
}
fn read_full(&self, tpe: FileType, id: &Id) -> RusticResult<Bytes> {
self.be_hot.read_full(tpe, id)
}
fn read_partial(
&self,
tpe: FileType,
id: &Id,
cacheable: bool,
offset: u32,
length: u32,
) -> RusticResult<Bytes> {
if cacheable || tpe != FileType::Pack {
self.be_hot.read_partial(tpe, id, cacheable, offset, length)
} else {
self.be.read_partial(tpe, id, cacheable, offset, length)
}
}
fn needs_warm_up(&self) -> bool {
self.be.needs_warm_up()
}
fn warm_up(&self, tpe: FileType, id: &Id) -> RusticResult<()> {
self.be.warm_up(tpe, id)
}
fn warmup_path(&self, tpe: FileType, id: &Id) -> String {
self.be.warmup_path(tpe, id)
}
}
impl WriteBackend for HotColdBackend {
fn create(&self) -> RusticResult<()> {
self.be.create()?;
self.be_hot.create()
}
fn write_bytes(&self, tpe: FileType, id: &Id, cacheable: bool, buf: Bytes) -> RusticResult<()> {
if tpe != FileType::Config && (cacheable || tpe != FileType::Pack) {
self.be_hot.write_bytes(tpe, id, cacheable, buf.clone())?;
}
self.be.write_bytes(tpe, id, cacheable, buf)
}
fn remove(&self, tpe: FileType, id: &Id, cacheable: bool) -> RusticResult<()> {
self.be.remove(tpe, id, cacheable)?;
if cacheable || tpe != FileType::Pack {
self.be_hot.remove(tpe, id, cacheable)?;
}
Ok(())
}
}