pub(crate) mod helpers;
use std::fmt::Debug;
use serde::de::DeserializeOwned;
use crate::error::StoreError;
use crate::types::IterationControlDecision;
pub enum IterationMode<'cfg_lt, OutK, OutV> {
Deserialize(Box<dyn FnMut(&[u8], &[u8]) -> Result<(OutK, OutV), StoreError> + 'cfg_lt>),
Raw,
ControlOnly,
}
pub enum IterationResult<'iter_lt, OutK, OutV> {
EffectCompleted,
RawItems(Box<dyn Iterator<Item = Result<(Vec<u8>, Vec<u8>), StoreError>> + 'iter_lt>),
DeserializedItems(Box<dyn Iterator<Item = Result<(OutK, OutV), StoreError>> + 'iter_lt>),
}
pub struct IterConfig<'cfg_lt, SerKey, OutK, OutV> {
pub cf_name: String,
pub prefix: Option<SerKey>,
pub start: Option<SerKey>,
pub reverse: bool,
pub control: Option<Box<dyn FnMut(&[u8], &[u8], usize) -> IterationControlDecision + 'cfg_lt>>,
pub mode: IterationMode<'cfg_lt, OutK, OutV>,
_phantom_cfg_lt: std::marker::PhantomData<&'cfg_lt ()>,
}
impl<'cfg_lt, SerKey, OutK, OutV> IterConfig<'cfg_lt, SerKey, OutK, OutV> {
pub fn new_deserializing(
cf_name: String,
prefix: Option<SerKey>,
start: Option<SerKey>,
reverse: bool,
control: Option<Box<dyn FnMut(&[u8], &[u8], usize) -> IterationControlDecision + 'cfg_lt>>,
deserializer: Box<dyn FnMut(&[u8], &[u8]) -> Result<(OutK, OutV), StoreError> + 'cfg_lt>,
) -> Self {
Self {
cf_name,
prefix,
start,
reverse,
control,
mode: IterationMode::Deserialize(deserializer),
_phantom_cfg_lt: std::marker::PhantomData,
}
}
}
impl<'cfg_lt, SerKey> IterConfig<'cfg_lt, SerKey, Vec<u8>, Vec<u8>> {
pub fn new_raw(
cf_name: String,
prefix: Option<SerKey>,
start: Option<SerKey>,
reverse: bool,
control: Option<Box<dyn FnMut(&[u8], &[u8], usize) -> IterationControlDecision + 'cfg_lt>>,
) -> Self {
Self {
cf_name,
prefix,
start,
reverse,
control,
mode: IterationMode::Raw,
_phantom_cfg_lt: std::marker::PhantomData,
}
}
}
impl<'cfg_lt, SerKey> IterConfig<'cfg_lt, SerKey, (), ()> {
pub fn new_control_only(
cf_name: String,
prefix: Option<SerKey>,
start: Option<SerKey>,
reverse: bool,
control: Box<dyn FnMut(&[u8], &[u8], usize) -> IterationControlDecision + 'cfg_lt>,
) -> Self {
Self {
cf_name,
prefix,
start,
reverse,
control: Some(control),
mode: IterationMode::ControlOnly,
_phantom_cfg_lt: std::marker::PhantomData,
}
}
}
pub struct ControlledIter<'iter_lt, R, OutK, OutV>
where
R: Iterator<Item = Result<(Box<[u8]>, Box<[u8]>), rocksdb::Error>> + 'iter_lt,
OutK: DeserializeOwned + Debug + 'iter_lt, OutV: DeserializeOwned + Debug + 'iter_lt, {
pub(crate) raw: R,
pub(crate) control: Option<Box<dyn FnMut(&[u8], &[u8], usize) -> IterationControlDecision + 'iter_lt>>,
pub(crate) deserializer: Box<dyn FnMut(&[u8], &[u8]) -> Result<(OutK, OutV), StoreError> + 'iter_lt>,
pub(crate) items_kept_count: usize,
pub(crate) _phantom_out: std::marker::PhantomData<(OutK, OutV)>, }
impl<'iter_lt, R, OutK, OutV> Iterator for ControlledIter<'iter_lt, R, OutK, OutV>
where
R: Iterator<Item = Result<(Box<[u8]>, Box<[u8]>), rocksdb::Error>> + 'iter_lt,
OutK: DeserializeOwned + Debug + 'iter_lt,
OutV: DeserializeOwned + Debug + 'iter_lt,
{
type Item = Result<(OutK, OutV), StoreError>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.raw.next() {
Some(Ok((key_bytes, val_bytes))) => {
if let Some(ref mut control_fn) = self.control {
match control_fn(&key_bytes, &val_bytes, self.items_kept_count) {
IterationControlDecision::Stop => return None,
IterationControlDecision::Skip => {
continue;
}
IterationControlDecision::Keep => {}
}
}
let deserialized_item = (self.deserializer)(&key_bytes, &val_bytes);
self.items_kept_count += 1;
return Some(deserialized_item);
}
Some(Err(e)) => return Some(Err(StoreError::RocksDb(e))),
None => return None,
}
}
}
}