use std::marker::PhantomData;
use bytes::Bytes;
use tempest_io::Io;
use crate::{
StorageError,
base::{Comparer, InternalKey, SeqNum},
iterator::StorageIterator,
};
pub(crate) struct SnapshotIterator<I, C, S>
where
I: Io,
C: Comparer,
S: StorageIterator<I, C>,
{
inner: S,
snapshot: SeqNum,
_marker: PhantomData<(I, C)>,
}
impl<I, C, S> SnapshotIterator<I, C, S>
where
I: Io,
C: Comparer,
S: StorageIterator<I, C>,
{
pub fn new(inner: S, snapshot: SeqNum) -> Self {
Self {
inner,
snapshot,
_marker: PhantomData,
}
}
}
impl<I, C, S> StorageIterator<I, C> for SnapshotIterator<I, C, S>
where
I: Io,
C: Comparer,
S: StorageIterator<I, C>,
{
async fn next(&mut self) -> Result<Option<(InternalKey<C, Bytes>, Bytes)>, StorageError> {
while let Some((key, value)) = self.inner.next().await? {
if key.trailer().seqnum() <= self.snapshot {
return Ok(Some((key, value)));
}
trace!(
key.len = key.key().len(),
entry_seqnum = key.trailer().seqnum().get(),
snapshot = self.snapshot.get(),
"snapshot_iter: skipping entry above snapshot"
);
}
Ok(None)
}
async fn seek(&mut self, key: InternalKey<C, Bytes>) -> Result<(), StorageError> {
self.inner.seek(key).await
}
}