use super::*;
#[async_trait::async_trait]
pub trait BloomDataProvider: Send + Sync {
async fn read_byte(&self, index: u64) -> Result<u8>;
}
#[async_trait::async_trait]
pub trait BloomProvider<Key: Send + Sync>: Sync + Send {
type Filter: FilterTrait<Key>;
async fn check_filter(&self, item: &Key) -> FilterResult;
fn check_filter_fast(&self, item: &Key) -> FilterResult;
async fn offload_buffer(&mut self, needed_memory: usize, level: usize) -> usize;
async fn get_filter(&self) -> Option<Self::Filter>;
fn get_filter_fast(&self) -> Option<&Self::Filter>;
async fn filter_memory_allocated(&self) -> usize;
}
#[async_trait::async_trait]
pub trait FilterTrait<Key: Send + Sync>: Clone + Sync + Send {
fn add(&self, key: &Key);
fn contains_fast(&self, key: &Key) -> FilterResult;
async fn contains<P: BloomDataProvider>(&self, _provider: &P, key: &Key) -> FilterResult {
self.contains_fast(key)
}
fn offload_filter(&mut self) -> usize {
0
}
#[must_use]
fn checked_add_assign(&mut self, other: &Self) -> bool;
fn memory_allocated(&self) -> usize {
0
}
fn clear_filter(&mut self);
fn is_filter_offloaded(&self) -> bool {
false
}
}
#[async_trait::async_trait]
impl<T, K> FilterTrait<K> for Option<T>
where
K: Send + Sync,
T: Send + Sync + Clone + FilterTrait<K>,
{
fn add(&self, key: &K) {
if let Some(filter) = self {
filter.add(key);
}
}
fn contains_fast(&self, key: &K) -> FilterResult {
if let Some(filter) = &self {
filter.contains_fast(key)
} else {
FilterResult::NeedAdditionalCheck
}
}
fn checked_add_assign(&mut self, other: &Self) -> bool {
match (self, other) {
(Some(this), Some(other)) => this.checked_add_assign(other),
(None, None) => true,
_ => false,
}
}
fn clear_filter(&mut self) {
if let Some(filter) = self {
filter.clear_filter();
}
}
async fn contains<P: BloomDataProvider>(&self, provider: &P, key: &K) -> FilterResult {
if let Some(filter) = &self {
filter.contains(provider, key).await
} else {
FilterResult::NeedAdditionalCheck
}
}
fn offload_filter(&mut self) -> usize {
if let Some(filter) = self {
filter.offload_filter()
} else {
0
}
}
fn memory_allocated(&self) -> usize {
if let Some(filter) = self {
filter.memory_allocated()
} else {
0
}
}
fn is_filter_offloaded(&self) -> bool {
if let Some(filter) = &self {
filter.is_filter_offloaded()
} else {
false
}
}
}