use crate::rpc::eth::FilterID;
use crate::rpc::Arc;
use ahash::AHashMap as HashMap;
use anyhow::anyhow;
use anyhow::Result;
use parking_lot::RwLock;
use std::any::Any;
pub trait Filter: Send + Sync + std::fmt::Debug {
fn id(&self) -> &FilterID;
fn as_any(&self) -> &dyn Any;
}
pub trait FilterStore: Send + Sync {
fn add(&self, filter: Arc<dyn Filter>) -> Result<()>;
fn get(&self, id: &FilterID) -> Result<Arc<dyn Filter>>;
fn remove(&self, id: &FilterID) -> Option<Arc<dyn Filter>>;
}
#[derive(Debug)]
pub struct MemFilterStore {
max: usize,
filters: RwLock<HashMap<FilterID, Arc<dyn Filter>>>,
}
impl MemFilterStore {
pub fn new(max_filters: usize) -> Arc<Self> {
Arc::new(Self {
max: max_filters,
filters: RwLock::new(HashMap::new()),
})
}
}
impl FilterStore for MemFilterStore {
fn add(&self, filter: Arc<dyn Filter>) -> Result<()> {
let mut filters = self.filters.write();
if filters.len() == self.max {
return Err(anyhow::Error::msg("Maximum number of filters registered"));
}
if filters.contains_key(filter.id()) {
return Err(anyhow::Error::msg("Filter already registered"));
}
filters.insert(filter.id().clone(), filter);
Ok(())
}
fn get(&self, id: &FilterID) -> Result<Arc<dyn Filter>> {
let filters = self.filters.read();
filters
.get(id)
.cloned()
.ok_or_else(|| anyhow!("Filter with the given ID not found"))
}
fn remove(&self, id: &FilterID) -> Option<Arc<dyn Filter>> {
let mut filters = self.filters.write();
filters.remove(id)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::rpc::eth::FilterID;
use std::sync::Arc;
#[derive(Debug)]
struct TestFilter {
id: FilterID,
}
impl Filter for TestFilter {
fn id(&self) -> &FilterID {
&self.id
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[test]
fn test_add_filter() {
let store = MemFilterStore::new(2);
let filter1 = Arc::new(TestFilter {
id: FilterID::new().unwrap(),
});
let filter2 = Arc::new(TestFilter {
id: FilterID::new().unwrap(),
});
let duplicate_filter = filter1.clone();
assert!(store.add(filter1.clone()).is_ok());
assert!(store.add(duplicate_filter.clone()).is_err());
assert!(store.add(filter2.clone()).is_ok());
let filter3 = Arc::new(TestFilter {
id: FilterID::new().unwrap(),
});
assert!(store.add(filter3.clone()).is_err());
}
}