use std::marker::PhantomData;
use std::sync::Arc;
use crate::engine::RegolithEngine;
use crate::engine::iterator::RegolithIterator;
use crate::statistics::{Histogram, Statistics, Ticker, TimeScope};
use crate::{DbSlice, Result};
pub struct Iter<'a> {
inner: RegolithIterator,
stats: Option<Arc<Statistics>>,
_marker: PhantomData<&'a RegolithEngine>,
}
impl<'a> Iter<'a> {
pub(crate) fn from_internal(inner: RegolithIterator) -> Self {
Self {
inner,
stats: None,
_marker: PhantomData,
}
}
pub(crate) fn with_stats(mut self, stats: Option<Arc<Statistics>>) -> Self {
self.stats = stats;
self
}
fn tick_seek(&self) {
if let Some(s) = self.stats.as_deref() {
s.add(Ticker::IterSeekCount, 1);
}
}
fn tick_next(&self) {
if let Some(s) = self.stats.as_deref() {
s.add(Ticker::IterNextCount, 1);
}
}
pub fn seek(&mut self, target: &[u8]) {
self.tick_seek();
let _t = TimeScope::new(self.stats.as_deref(), Histogram::DbIterSeek);
self.inner.seek(target);
}
pub fn seek_for_prev(&mut self, target: &[u8]) {
self.tick_seek();
let _t = TimeScope::new(self.stats.as_deref(), Histogram::DbIterSeek);
self.inner.seek_for_prev(target);
}
pub fn seek_prefix(&mut self, prefix: &[u8]) {
self.tick_seek();
let _t = TimeScope::new(self.stats.as_deref(), Histogram::DbIterSeek);
self.inner.seek_prefix(prefix);
}
pub fn seek_to_first(&mut self) {
self.tick_seek();
let _t = TimeScope::new(self.stats.as_deref(), Histogram::DbIterSeek);
self.inner.seek_to_first();
}
pub fn seek_to_last(&mut self) {
self.tick_seek();
let _t = TimeScope::new(self.stats.as_deref(), Histogram::DbIterSeek);
self.inner.seek_to_last();
}
pub(crate) fn seek_to_last_before(&mut self, exclusive_upper: &[u8]) {
self.tick_seek();
let _t = TimeScope::new(self.stats.as_deref(), Histogram::DbIterSeek);
self.inner.seek_to_last_before(exclusive_upper);
}
pub fn next(&mut self) {
let _t = TimeScope::new(self.stats.as_deref(), Histogram::DbIterNext);
self.inner.next();
if self.inner.valid() {
self.tick_next();
}
}
pub fn prev(&mut self) {
let _t = TimeScope::new(self.stats.as_deref(), Histogram::DbIterNext);
self.inner.prev();
if self.inner.valid() {
self.tick_next();
}
}
pub fn positioned(&self) -> bool {
self.inner.positioned()
}
pub fn valid(&self) -> bool {
self.inner.valid()
}
pub fn key(&self) -> Option<&[u8]> {
self.inner.key()
}
pub fn value(&self) -> Option<&[u8]> {
self.inner.value()
}
pub fn value_slice(&self) -> Option<DbSlice> {
self.inner.value_slice()
}
pub fn status(&self) -> Result<()> {
self.inner.status().map_err(crate::Error::from)
}
}