use std::{cmp::Ordering, ops::Range};
use crate::{
storage::{Item, ItemIterator, Storage},
MergeIters, StorageError, ID,
};
pub struct TieredStorage<A: Storage, B: Storage> {
a: A,
b: B,
id: ID,
}
impl<A: Storage, B: Storage> TieredStorage<A, B> {
pub fn new(a: A, b: B) -> Self {
Self {
a,
b,
id: ID::new(),
}
}
}
impl PartialEq for StorageError {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Miscellaneous(_), Self::Miscellaneous(_)) => true,
_ => core::mem::discriminant(self) == core::mem::discriminant(other),
}
}
}
impl Eq for StorageError {}
impl PartialOrd for StorageError {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for StorageError {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
match (self, other) {
(StorageError::ConcurrencyError, StorageError::ConcurrencyError) => Ordering::Equal,
(StorageError::ConcurrencyError, StorageError::Miscellaneous(_)) => Ordering::Less,
(StorageError::Miscellaneous(_), StorageError::ConcurrencyError) => Ordering::Greater,
(StorageError::Miscellaneous(_), StorageError::Miscellaneous(_)) => Ordering::Equal,
}
}
}
impl<A: Storage, B: Storage> Storage for TieredStorage<A, B> {
fn range(&self, r: Range<&[u8]>) -> Result<ItemIterator<'_>, StorageError> {
let iters = vec![self.a.range(r.clone())?, self.b.range(r.clone())?];
let merged = MergeIters::new(iters);
Ok(Box::new(merged.map(|x| x.0)))
}
fn insert(&self, is: &[Item]) -> Result<(), StorageError> {
self.a.insert(is)?;
self.b.insert(is)?;
Ok(())
}
fn id(&self) -> ID {
self.id
}
}