use crate::{InternalValue, UserKey, comparator::SharedComparator};
use alloc::collections::VecDeque;
use core::{cell::RefCell, cmp::Ordering, iter::Peekable};
#[derive(Default)]
#[doc(hidden)]
pub struct OverwrittenKeys(RefCell<VecDeque<UserKey>>);
impl OverwrittenKeys {
pub(crate) fn take_before_and_check(&self, key: &[u8], comparator: &SharedComparator) -> bool {
let mut queue = self.0.borrow_mut();
while let Some(front) = queue.front() {
match comparator.compare(front, key) {
Ordering::Less => {
queue.pop_front();
}
Ordering::Equal => return true,
Ordering::Greater => return false,
}
}
false
}
fn mark(&self, key: &UserKey) {
let mut queue = self.0.borrow_mut();
if queue
.back()
.is_none_or(|last| !crate::comparator::same_user_key(last, key))
{
queue.push_back(key.clone());
}
}
}
pub struct MarkOverwritten<'q, I: Iterator<Item = crate::Result<InternalValue>>> {
inner: Peekable<I>,
keys: Option<&'q OverwrittenKeys>,
}
impl<'q, I: Iterator<Item = crate::Result<InternalValue>>> MarkOverwritten<'q, I> {
pub(crate) fn new(inner: I, keys: Option<&'q OverwrittenKeys>) -> Self {
Self {
inner: inner.peekable(),
keys,
}
}
}
impl<I: Iterator<Item = crate::Result<InternalValue>>> Iterator for MarkOverwritten<'_, I> {
type Item = crate::Result<InternalValue>;
fn next(&mut self) -> Option<Self::Item> {
let item = self.inner.next()?;
if let (Some(keys), Ok(current)) = (self.keys, &item)
&& let Some(Ok(next)) = self.inner.peek()
&& crate::comparator::same_user_key(&next.key.user_key, ¤t.key.user_key)
{
keys.mark(¤t.key.user_key);
}
Some(item)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[cfg(test)]
mod tests;