use std::marker::PhantomData;
use cid::Cid;
use fvm_ipld_blockstore::Blockstore;
use crate::v17::{ActorError, Config, Map2, MapKey};
use super::Set;
pub struct SetMultimapConfig {
pub outer: Config,
pub inner: Config,
}
pub struct SetMultimap<BS, K, V>
where
BS: Blockstore,
K: MapKey,
V: MapKey,
{
outer: Map2<BS, K, Cid>,
inner_config: Config,
value_type: PhantomData<V>,
}
impl<BS, K, V> SetMultimap<BS, K, V>
where
BS: Blockstore,
K: MapKey,
V: MapKey,
{
pub fn empty(bs: BS, config: SetMultimapConfig, name: &'static str) -> Self {
Self {
outer: Map2::empty(bs, config.outer, name),
inner_config: config.inner,
value_type: Default::default(),
}
}
pub fn load(
bs: BS,
root: &Cid,
config: SetMultimapConfig,
name: &'static str,
) -> Result<Self, ActorError> {
Ok(Self {
outer: Map2::load(bs, root, config.outer, name)?,
inner_config: config.inner,
value_type: Default::default(),
})
}
#[inline]
pub fn flush(&mut self) -> Result<Cid, ActorError> {
self.outer.flush()
}
pub fn put(&mut self, key: &K, value: V) -> Result<(), ActorError> {
let mut inner = self.get(key)?.unwrap_or_else(|| {
Set::empty(
self.outer.store(),
self.inner_config.clone(),
"multimap inner",
)
});
inner.put(&value)?;
let new_root = inner.flush()?;
self.outer.set(key, new_root)?;
Ok(())
}
pub fn put_many(&mut self, key: &K, values: &[V]) -> Result<(), ActorError> {
let mut inner = self.get(key)?.unwrap_or_else(|| {
Set::empty(
self.outer.store(),
self.inner_config.clone(),
"multimap inner",
)
});
for v in values {
inner.put(v)?;
}
let new_root = inner.flush()?;
self.outer.set(key, new_root)?;
Ok(())
}
#[inline]
pub fn get(&self, key: &K) -> Result<Option<Set<&BS, V>>, ActorError> {
match self.outer.get(key)? {
Some(cid) => Ok(Some(Set::load(
self.outer.store(),
cid,
self.inner_config.clone(),
"multimap inner",
)?)),
None => Ok(None),
}
}
#[inline]
pub fn remove(&mut self, key: &K, value: V) -> Result<(), ActorError> {
let mut set = match self.get(key)? {
Some(s) => s,
None => return Ok(()),
};
set.delete(&value)?;
let new_root = set.flush()?;
self.outer.set(key, new_root)?;
Ok(())
}
#[inline]
pub fn remove_all(&mut self, key: &K) -> Result<(), ActorError> {
self.outer.delete(key)?;
Ok(())
}
pub fn for_each<F>(&self, mut f: F) -> Result<(), ActorError>
where
F: FnMut(K, &Cid) -> Result<(), ActorError>,
{
self.outer.for_each(|k, v| f(k, v))
}
pub fn for_each_in<F>(&self, key: &K, f: F) -> Result<(), ActorError>
where
F: FnMut(V) -> Result<(), ActorError>,
{
let set = match self.get(key)? {
Some(s) => s,
None => return Ok(()),
};
set.for_each(f)
}
}