use crate::comparator::Comparator;
use crate::format::{
append_internal_key, parse_internal_key, ParsedInternalKey, SequenceNumber, ValueType,
READ_BYTES_PERIOD, VALUE_TYPE_FOR_SEEK,
};
use crate::status::{Result, Status};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Direction {
Forward,
Reverse,
}
type ReadSampler = Box<dyn FnMut(&[u8]) + Send>;
pub struct DBIter<C: Comparator, I: crate::db_iter::DbIterator> {
user_comparator: C,
iter: I,
sequence: SequenceNumber,
direction: Direction,
valid: bool,
saved_key: Vec<u8>,
saved_value: Vec<u8>,
status: Result<()>,
sampler: Option<ReadSampler>,
bytes_counter: i64,
read_bytes_period: i64,
drop_hook: Option<Box<dyn FnMut() + Send>>,
}
impl<C: Comparator, I: crate::db_iter::DbIterator> DBIter<C, I> {
pub fn new(user_comparator: C, iter: I, sequence: SequenceNumber) -> Self {
Self {
user_comparator,
iter,
sequence,
direction: Direction::Forward,
valid: false,
saved_key: Vec::new(),
saved_value: Vec::new(),
status: Ok(()),
sampler: None,
bytes_counter: READ_BYTES_PERIOD as i64,
read_bytes_period: READ_BYTES_PERIOD as i64,
drop_hook: None,
}
}
pub fn set_sampler(&mut self, sampler: ReadSampler) {
self.sampler = Some(sampler);
}
pub fn set_drop_hook(&mut self, drop_hook: Box<dyn FnMut() + Send>) {
self.drop_hook = Some(drop_hook);
}
pub fn set_read_bytes_period(&mut self, period: i64) {
self.read_bytes_period = period.max(1);
self.bytes_counter = self.read_bytes_period;
}
fn maybe_sample(&mut self) {
let n = (self.iter.key().len() + self.iter.value().len()) as i64;
self.bytes_counter -= n;
while self.bytes_counter < 0 {
self.bytes_counter += self.read_bytes_period;
if let Some(s) = self.sampler.as_mut() {
s(self.iter.key());
}
}
}
pub fn valid(&self) -> bool {
self.valid
}
pub fn key(&self) -> &[u8] {
assert!(self.valid, "DBIter::key on invalid iterator");
match self.direction {
Direction::Forward => {
let k = self.iter.key();
&k[..k.len() - 8]
}
Direction::Reverse => &self.saved_key,
}
}
pub fn value(&self) -> &[u8] {
assert!(self.valid, "DBIter::value on invalid iterator");
match self.direction {
Direction::Forward => self.iter.value(),
Direction::Reverse => &self.saved_value,
}
}
pub fn status(&self) -> Result<()> {
match &self.status {
Ok(()) => self.iter.status(),
Err(e) => Err(e.clone()),
}
}
pub fn seek_to_first(&mut self) {
self.direction = Direction::Forward;
self.saved_value.clear();
self.iter.seek_to_first();
if self.iter.valid() {
self.find_next_user_entry(false);
} else {
self.valid = false;
}
}
pub fn seek_to_last(&mut self) {
self.direction = Direction::Reverse;
self.saved_value.clear();
self.iter.seek_to_last();
self.find_prev_user_entry();
}
pub fn seek(&mut self, target: &[u8]) {
self.direction = Direction::Forward;
self.saved_value.clear();
self.saved_key.clear();
append_internal_key(
&mut self.saved_key,
&ParsedInternalKey::new(target, self.sequence, VALUE_TYPE_FOR_SEEK),
);
let saved_internal = self.saved_key.clone();
self.iter.seek(&saved_internal);
if self.iter.valid() {
self.find_next_user_entry(false);
} else {
self.valid = false;
}
}
pub fn next(&mut self) {
assert!(self.valid, "DBIter::next on invalid iterator");
if self.direction == Direction::Reverse {
self.direction = Direction::Forward;
if !self.iter.valid() {
self.iter.seek_to_first();
} else {
self.iter.next();
}
if !self.iter.valid() {
self.valid = false;
self.saved_key.clear();
return;
}
} else {
let cur = self.iter.key();
let user_key = &cur[..cur.len() - 8];
self.saved_key.clear();
self.saved_key.extend_from_slice(user_key);
}
self.find_next_user_entry(true);
}
pub fn prev(&mut self) {
assert!(self.valid, "DBIter::prev on invalid iterator");
if self.direction == Direction::Forward {
let cur_user = {
let k = self.iter.key();
k[..k.len() - 8].to_vec()
};
self.saved_key = cur_user;
loop {
self.iter.prev();
if !self.iter.valid() {
self.valid = false;
self.saved_key.clear();
self.saved_value.clear();
return;
}
let k = self.iter.key();
let uk = &k[..k.len() - 8];
if self.user_comparator.compare(uk, &self.saved_key).is_lt() {
break;
}
}
self.direction = Direction::Reverse;
}
self.find_prev_user_entry();
}
fn find_next_user_entry(&mut self, mut skipping: bool) {
assert!(self.iter.valid());
assert!(self.direction == Direction::Forward);
loop {
self.maybe_sample();
let parsed = match parse_internal_key(self.iter.key()) {
Some(p) => p,
None => {
self.status = Err(Status::corruption("corrupted internal key in DBIter"));
self.valid = false;
return;
}
};
if parsed.sequence <= self.sequence {
match parsed.value_type {
ValueType::Deletion => {
self.saved_key.clear();
self.saved_key.extend_from_slice(&parsed.user_key);
skipping = true;
}
ValueType::Value => {
let shadowed = skipping
&& self
.user_comparator
.compare(&parsed.user_key, &self.saved_key)
.is_le();
if !shadowed {
self.valid = true;
self.saved_key.clear();
return;
}
}
}
}
self.iter.next();
if !self.iter.valid() {
break;
}
}
self.saved_key.clear();
self.valid = false;
}
fn find_prev_user_entry(&mut self) {
assert!(self.direction == Direction::Reverse);
let mut value_type = ValueType::Deletion;
if self.iter.valid() {
loop {
self.maybe_sample();
let parsed = match parse_internal_key(self.iter.key()) {
Some(p) => p,
None => {
self.status = Err(Status::corruption("corrupted internal key in DBIter"));
self.valid = false;
return;
}
};
if parsed.sequence <= self.sequence {
if value_type != ValueType::Deletion
&& self
.user_comparator
.compare(&parsed.user_key, &self.saved_key)
.is_lt()
{
break;
}
value_type = parsed.value_type;
if value_type == ValueType::Deletion {
self.saved_key.clear();
self.saved_value.clear();
} else {
let raw_value = self.iter.value();
self.saved_key.clear();
self.saved_key.extend_from_slice(&parsed.user_key);
self.saved_value.clear();
self.saved_value.extend_from_slice(raw_value);
}
}
self.iter.prev();
if !self.iter.valid() {
break;
}
}
}
if value_type == ValueType::Deletion {
self.valid = false;
self.saved_key.clear();
self.saved_value.clear();
self.direction = Direction::Forward;
} else {
self.valid = true;
}
}
}
impl<C: Comparator, I: crate::db_iter::DbIterator> crate::db_iter::DbIterator for DBIter<C, I> {
fn valid(&self) -> bool {
DBIter::valid(self)
}
fn seek_to_first(&mut self) {
DBIter::seek_to_first(self)
}
fn seek_to_last(&mut self) {
DBIter::seek_to_last(self)
}
fn seek(&mut self, target: &[u8]) {
DBIter::seek(self, target)
}
fn next(&mut self) {
DBIter::next(self)
}
fn prev(&mut self) {
DBIter::prev(self)
}
fn key(&self) -> &[u8] {
DBIter::key(self)
}
fn value(&self) -> &[u8] {
DBIter::value(self)
}
fn status(&self) -> Result<()> {
DBIter::status(self)
}
}
impl<C: Comparator, I: crate::db_iter::DbIterator> Drop for DBIter<C, I> {
fn drop(&mut self) {
if let Some(mut drop_hook) = self.drop_hook.take() {
drop_hook();
}
}
}