use tessarikv_types::{SequenceNumber, Trailer, ValueKind, encode_internal, seek_trailer};
use super::DbIterator;
use crate::Result;
impl DbIterator<'_> {
pub async fn seek_to_last(&mut self) -> Result<()> {
match self.upper.take() {
Some(upper) => {
let moved = self.before(&upper).await;
self.upper = Some(upper);
moved
}
None => {
self.valid = false;
self.versions.seek_to_last().await;
self.settle_backward().await
}
}
}
pub async fn seek_for_prev(&mut self, key: &[u8]) -> Result<()> {
if self.upper.as_deref().is_some_and(|upper| upper <= key) {
return self.seek_to_last().await;
}
let mut target = Vec::new();
encode_internal(
key,
Trailer::new(SequenceNumber::ZERO, ValueKind::Delete),
&mut target,
);
self.valid = false;
self.versions.seek_for_prev(&target).await;
self.settle_backward().await
}
pub async fn prev(&mut self) -> Result<()> {
if !self.valid {
return Ok(());
}
if self.backward {
return self.settle_backward().await;
}
let key = std::mem::take(&mut self.key);
self.before(&key).await
}
async fn before(&mut self, key: &[u8]) -> Result<()> {
let mut target = Vec::new();
encode_internal(key, seek_trailer(SequenceNumber::MAX), &mut target);
self.valid = false;
self.versions.seek_for_prev(&target).await;
self.settle_backward().await
}
async fn settle_backward(&mut self) -> Result<()> {
self.backward = true;
self.valid = false;
while let Some(version) = self.versions.entry() {
if self
.lower
.as_deref()
.is_some_and(|lower| version.user_key < lower)
{
break;
}
self.key.clear();
self.key.extend_from_slice(version.user_key);
let mut live = false;
while let Some(version) = self.versions.entry() {
if version.user_key != self.key.as_slice() {
break;
}
if version.sequence <= self.snapshot {
live = version.kind == ValueKind::Value
&& !self.fragments.deletes(version.user_key, version.sequence);
if live {
self.saved.clear();
self.saved.extend_from_slice(version.value);
}
}
self.versions.prev().await;
}
if live {
self.valid = true;
break;
}
}
if !self.valid {
self.key.clear();
}
self.finish_move()
}
}