use std::cmp::Ordering;
use std::fs::File;
use std::ops::Bound;
use std::sync::Arc;
use crossbeam_skiplist::SkipSet;
use parking_lot::RwLockReadGuard;
use crate::bplustree::tree::{BPlusTreeIterator, DiskBPlusTree};
use crate::error::{Error, Result};
use crate::iter::BoxedLSMIterator;
use crate::levels::Levels;
use crate::lsm::Core;
use crate::memtable::MemTable;
use crate::{
BytewiseComparator,
Comparator,
InternalKey,
InternalKeyComparator,
InternalKeyKind,
InternalKeyRange,
InternalKeyRef,
LSMIterator,
TimestampComparator,
Value,
};
pub(crate) struct SnapshotTracker {
snapshots: Arc<SkipSet<u64>>,
}
impl Clone for SnapshotTracker {
fn clone(&self) -> Self {
Self {
snapshots: Arc::clone(&self.snapshots),
}
}
}
impl Default for SnapshotTracker {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for SnapshotTracker {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SnapshotTracker").field("snapshots", &self.get_all_snapshots()).finish()
}
}
impl SnapshotTracker {
pub(crate) fn new() -> Self {
Self {
snapshots: Arc::new(SkipSet::new()),
}
}
pub(crate) fn register(&self, seq_num: u64) {
self.snapshots.insert(seq_num);
}
pub(crate) fn unregister(&self, seq_num: u64) {
self.snapshots.remove(&seq_num);
}
pub(crate) fn get_all_snapshots(&self) -> Vec<u64> {
self.snapshots.iter().map(|entry| *entry).collect()
}
}
pub(crate) struct IterState {
pub active: Arc<MemTable>,
pub immutable: Vec<Arc<MemTable>>,
pub levels: Levels,
pub versioned_index: Option<Arc<parking_lot::RwLock<DiskBPlusTree>>>,
}
pub(crate) struct Snapshot {
core: Arc<Core>,
pub(crate) seq_num: u64,
}
impl Snapshot {
pub(crate) fn new(core: Arc<Core>, seq_num: u64) -> Self {
core.snapshot_tracker.register(seq_num);
Self {
core,
seq_num,
}
}
pub(crate) fn collect_iter_state(&self) -> Result<IterState> {
let active = guardian::ArcRwLockReadGuardian::take(Arc::clone(&self.core.active_memtable))?;
let immutable =
guardian::ArcRwLockReadGuardian::take(Arc::clone(&self.core.immutable_memtables))?;
let manifest =
guardian::ArcRwLockReadGuardian::take(Arc::clone(&self.core.level_manifest))?;
Ok(IterState {
active: active.clone(),
immutable: immutable.iter().map(|entry| Arc::clone(&entry.memtable)).collect(),
levels: manifest.levels.clone(),
versioned_index: self.core.versioned_index.clone(),
})
}
pub(crate) fn get(&self, key: &[u8]) -> crate::Result<Option<(Value, u64)>> {
let memtable_lock = self.core.active_memtable.read()?;
if let Some(item) = memtable_lock.get(key.as_ref(), Some(self.seq_num)) {
if item.0.is_tombstone() {
return Ok(None); }
return Ok(Some((item.1, item.0.seq_num()))); }
drop(memtable_lock);
let memtable_lock = self.core.immutable_memtables.read()?;
for entry in memtable_lock.iter().rev() {
let memtable = &entry.memtable;
if let Some(item) = memtable.get(key.as_ref(), Some(self.seq_num)) {
if item.0.is_tombstone() {
return Ok(None); }
return Ok(Some((item.1, item.0.seq_num()))); }
}
drop(memtable_lock);
let level_manifest = self.core.level_manifest.read()?;
let ikey = InternalKey::new(key.to_vec(), self.seq_num, InternalKeyKind::Set, 0);
for (level_idx, level) in (&level_manifest.levels).into_iter().enumerate() {
if level_idx == 0 {
for table in level.tables.iter() {
if !table.is_key_in_key_range(&ikey) {
continue; }
let maybe_item = table.get(&ikey)?;
if let Some(item) = maybe_item {
let ikey = &item.0;
if ikey.is_tombstone() {
return Ok(None); }
return Ok(Some((item.1, ikey.seq_num()))); }
}
} else {
let query_range =
crate::user_range_to_internal_range(Bound::Included(key), Bound::Included(key));
let start_idx = level.find_first_overlapping_table(&query_range);
let end_idx = level.find_last_overlapping_table(&query_range);
for table in &level.tables[start_idx..end_idx] {
let maybe_item = table.get(&ikey)?;
if let Some(item) = maybe_item {
let ikey = &item.0;
if ikey.is_tombstone() {
return Ok(None); }
return Ok(Some((item.1, ikey.seq_num()))); }
}
}
}
Ok(None) }
pub(crate) fn range(
&self,
lower: Option<&[u8]>,
upper: Option<&[u8]>,
) -> Result<SnapshotIterator<'_>> {
let internal_range = crate::user_range_to_internal_range(
lower.map(Bound::Included).unwrap_or(Bound::Unbounded),
upper.map(Bound::Excluded).unwrap_or(Bound::Unbounded),
);
SnapshotIterator::new_from(Arc::clone(&self.core), self.seq_num, internal_range)
}
pub(crate) fn history_iter(
&self,
lower: Option<&[u8]>,
upper: Option<&[u8]>,
include_tombstones: bool,
ts_range: Option<(u64, u64)>,
limit: Option<usize>,
) -> Result<HistoryIterator<'_>> {
if !self.core.opts.enable_versioning {
return Err(Error::InvalidArgument("Versioning not enabled".to_string()));
}
let range = crate::user_range_to_internal_range(
lower.map(Bound::Included).unwrap_or(Bound::Unbounded),
upper.map(Bound::Excluded).unwrap_or(Bound::Unbounded),
);
let iter_state = self.collect_iter_state()?;
if self.core.opts.enable_versioned_index {
let merge_iter = KMergeIterator::new_for_history_with_btree(iter_state, range)?;
Ok(HistoryIterator::new(
merge_iter,
self.seq_num,
include_tombstones,
lower,
upper,
ts_range,
limit,
))
} else {
Ok(HistoryIterator::new_lsm(
self.seq_num,
iter_state,
range,
include_tombstones,
ts_range,
limit,
lower,
upper,
))
}
}
pub(crate) fn get_at(&self, key: &[u8], timestamp: u64) -> Result<Option<Value>> {
let mut iter = self.history_iter(Some(key), None, true, None, None)?;
iter.seek_first()?;
let mut best_value: Option<Value> = None;
let mut best_timestamp: u64 = 0;
while iter.valid() {
let entry_key = iter.key();
if entry_key.user_key() != key {
break;
}
if entry_key.seq_num() > self.seq_num {
iter.next()?;
continue;
}
let entry_ts = entry_key.timestamp();
if entry_ts <= timestamp && entry_ts >= best_timestamp {
if entry_key.is_tombstone() {
best_value = None;
} else {
best_value = Some(self.core.resolve_value(iter.value_encoded()?)?);
}
best_timestamp = entry_ts;
}
iter.next()?;
}
Ok(best_value)
}
}
impl Drop for Snapshot {
fn drop(&mut self) {
self.core.snapshot_tracker.unregister(self.seq_num);
}
}
#[derive(Clone, Copy, PartialEq)]
pub(crate) enum MergeDirection {
Forward,
Backward,
}
pub(crate) struct KMergeIterator<'iter> {
iterators: Vec<BoxedLSMIterator<'iter>>,
#[allow(dead_code)]
iter_state: Box<IterState>,
winner: Option<usize>,
active_count: usize,
direction: MergeDirection,
initialized: bool,
cmp: Arc<dyn Comparator>,
}
impl<'a> KMergeIterator<'a> {
pub(crate) fn new_from(iter_state: IterState, internal_range: InternalKeyRange) -> Self {
let cmp: Arc<dyn Comparator> =
Arc::new(InternalKeyComparator::new(Arc::new(BytewiseComparator::default())));
Self::new_with_comparator(iter_state, internal_range, cmp, None)
}
pub(crate) fn new_for_history(
iter_state: IterState,
internal_range: InternalKeyRange,
ts_range: Option<(u64, u64)>,
) -> Self {
let cmp: Arc<dyn Comparator> =
Arc::new(TimestampComparator::new(Arc::new(BytewiseComparator::default())));
Self::new_with_comparator(iter_state, internal_range, cmp, ts_range)
}
pub(crate) fn new_for_history_with_btree(
iter_state: IterState,
internal_range: InternalKeyRange,
) -> Result<Self> {
let cmp: Arc<dyn Comparator> =
Arc::new(TimestampComparator::new(Arc::new(BytewiseComparator::default())));
let boxed_state = Box::new(iter_state);
let mut iterators: Vec<BoxedLSMIterator<'a>> =
Vec::with_capacity(1 + boxed_state.immutable.len() + 1);
let state_ref: &'a IterState = unsafe { &*(&*boxed_state as *const IterState) };
let (ref start_bound, ref end_bound) = internal_range;
let lower = match start_bound {
Bound::Included(key) | Bound::Excluded(key) => Some(key.user_key.as_slice()),
Bound::Unbounded => None,
};
let upper = match end_bound {
Bound::Excluded(key) => Some(key.user_key.as_slice()),
Bound::Included(_) | Bound::Unbounded => None,
};
let active_iter = state_ref.active.range(lower, upper);
iterators.push(Box::new(active_iter) as BoxedLSMIterator<'a>);
for memtable in &state_ref.immutable {
let iter = memtable.range(lower, upper);
iterators.push(Box::new(iter) as BoxedLSMIterator<'a>);
}
if let Some(ref btree_arc) = state_ref.versioned_index {
let btree_iter = BPlusTreeIteratorWithGuard::new(btree_arc)?;
iterators.push(Box::new(btree_iter) as BoxedLSMIterator<'a>);
}
Ok(Self {
iterators,
iter_state: boxed_state,
winner: None,
active_count: 0,
direction: MergeDirection::Forward,
initialized: false,
cmp,
})
}
fn new_with_comparator(
iter_state: IterState,
internal_range: InternalKeyRange,
cmp: Arc<dyn Comparator>,
ts_range: Option<(u64, u64)>,
) -> Self {
let boxed_state = Box::new(iter_state);
let query_range = Arc::new(internal_range);
let mut iterators: Vec<BoxedLSMIterator<'a>> =
Vec::with_capacity(1 + boxed_state.immutable.len() + boxed_state.levels.total_tables());
let state_ref: &'a IterState = unsafe { &*(&*boxed_state as *const IterState) };
let (start_bound, end_bound) = query_range.as_ref();
let lower = match start_bound {
Bound::Included(key) | Bound::Excluded(key) => Some(key.user_key.as_slice()),
Bound::Unbounded => None,
};
let upper = match end_bound {
Bound::Excluded(key) => Some(key.user_key.as_slice()),
Bound::Included(_) | Bound::Unbounded => None,
};
let active_iter = state_ref.active.range(lower, upper);
iterators.push(Box::new(active_iter) as BoxedLSMIterator<'a>);
for memtable in &state_ref.immutable {
let iter = memtable.range(lower, upper);
iterators.push(Box::new(iter) as BoxedLSMIterator<'a>);
}
for (level_idx, level) in (&state_ref.levels).into_iter().enumerate() {
if level_idx == 0 {
for table in &level.tables {
if table.is_before_range(&query_range) || table.is_after_range(&query_range) {
continue;
}
if let Some((ts_start, ts_end)) = ts_range {
let props = &table.meta.properties;
if let (Some(newest), Some(oldest)) =
(props.newest_key_time, props.oldest_key_time)
{
if newest < ts_start || oldest > ts_end {
continue;
}
}
}
if let Ok(table_iter) =
table.iter_with_comparator(Some((*query_range).clone()), Arc::clone(&cmp))
{
iterators.push(Box::new(table_iter) as BoxedLSMIterator<'a>);
}
}
} else {
let start_idx = level.find_first_overlapping_table(&query_range);
let end_idx = level.find_last_overlapping_table(&query_range);
for table in &level.tables[start_idx..end_idx] {
if let Some((ts_start, ts_end)) = ts_range {
let props = &table.meta.properties;
if let (Some(newest), Some(oldest)) =
(props.newest_key_time, props.oldest_key_time)
{
if newest < ts_start || oldest > ts_end {
continue;
}
}
}
if let Ok(table_iter) =
table.iter_with_comparator(Some((*query_range).clone()), Arc::clone(&cmp))
{
iterators.push(Box::new(table_iter) as BoxedLSMIterator<'a>);
}
}
}
}
Self {
iterators,
iter_state: boxed_state,
winner: None,
active_count: 0,
direction: MergeDirection::Forward,
initialized: false,
cmp,
}
}
#[inline]
fn compare(&self, a: usize, b: usize) -> Ordering {
let iter_a = &self.iterators[a];
let iter_b = &self.iterators[b];
let valid_a = iter_a.valid();
let valid_b = iter_b.valid();
match (valid_a, valid_b) {
(false, false) => Ordering::Equal,
(true, false) => Ordering::Less, (false, true) => Ordering::Greater, (true, true) => {
let key_a = iter_a.key().encoded();
let key_b = iter_b.key().encoded();
let ord = self.cmp.compare(key_a, key_b);
if self.direction == MergeDirection::Backward {
ord.reverse()
} else {
ord
}
}
}
}
fn find_winner(&mut self) {
if self.iterators.is_empty() || self.active_count == 0 {
self.winner = None;
return;
}
let mut best_idx = None;
for i in 0..self.iterators.len() {
if !self.iterators[i].valid() {
continue;
}
match best_idx {
None => best_idx = Some(i),
Some(b) => {
if self.compare(i, b) == Ordering::Less {
best_idx = Some(i);
}
}
}
}
self.winner = best_idx;
}
fn init_forward(&mut self) -> Result<()> {
self.direction = MergeDirection::Forward;
self.active_count = 0;
for iter in &mut self.iterators {
if iter.seek_first()? {
self.active_count += 1;
}
}
self.find_winner();
self.initialized = true;
Ok(())
}
fn init_backward(&mut self) -> Result<()> {
self.direction = MergeDirection::Backward;
self.active_count = 0;
for iter in &mut self.iterators {
if iter.seek_last()? {
self.active_count += 1;
}
}
self.find_winner();
self.initialized = true;
Ok(())
}
fn switch_to_forward(&mut self, target: &[u8]) -> Result<()> {
let current_idx = self.winner;
self.direction = MergeDirection::Forward;
self.active_count = 0;
for (idx, iter) in self.iterators.iter_mut().enumerate() {
if Some(idx) == current_idx {
if iter.next()? {
self.active_count += 1;
}
} else {
if iter.seek(target)? {
while iter.valid()
&& self.cmp.compare(iter.key().encoded(), target) != Ordering::Greater
{
if !iter.next()? {
break;
}
}
if iter.valid() {
self.active_count += 1;
}
}
}
}
self.find_winner();
Ok(())
}
fn switch_to_backward(&mut self, target: &[u8]) -> Result<()> {
let current_idx = self.winner;
self.direction = MergeDirection::Backward;
self.active_count = 0;
for (idx, iter) in self.iterators.iter_mut().enumerate() {
if Some(idx) == current_idx {
if iter.prev()? {
self.active_count += 1;
}
} else {
if iter.seek(target)? {
while iter.valid()
&& self.cmp.compare(iter.key().encoded(), target) != Ordering::Less
{
if !iter.prev()? {
break;
}
}
if iter.valid() {
self.active_count += 1;
}
} else {
if iter.seek_last()? {
self.active_count += 1;
}
}
}
}
self.find_winner();
Ok(())
}
fn advance_winner(&mut self) -> Result<bool> {
if self.active_count == 0 || self.winner.is_none() {
return Ok(false);
}
let winner_idx = self.winner.unwrap();
let iter = &mut self.iterators[winner_idx];
let still_valid = if self.direction == MergeDirection::Forward {
iter.next()?
} else {
iter.prev()?
};
if !still_valid {
self.active_count = self.active_count.saturating_sub(1);
}
self.find_winner();
Ok(self.winner.is_some())
}
#[inline]
pub fn is_valid(&self) -> bool {
self.winner.is_some() && self.iterators[self.winner.unwrap()].valid()
}
}
impl LSMIterator for KMergeIterator<'_> {
fn seek(&mut self, target: &[u8]) -> Result<bool> {
self.direction = MergeDirection::Forward;
self.active_count = 0;
for iter in &mut self.iterators {
if iter.seek(target)? {
self.active_count += 1;
}
}
self.find_winner();
self.initialized = true;
Ok(self.is_valid())
}
fn seek_first(&mut self) -> Result<bool> {
self.init_forward()?;
Ok(self.is_valid())
}
fn seek_last(&mut self) -> Result<bool> {
self.init_backward()?;
Ok(self.is_valid())
}
fn next(&mut self) -> Result<bool> {
if !self.initialized {
return self.seek_first();
}
if !self.is_valid() {
return Ok(false);
}
if self.direction != MergeDirection::Forward {
let target = self.key().encoded().to_vec();
self.switch_to_forward(&target)?;
return Ok(self.is_valid());
}
self.advance_winner()
}
fn prev(&mut self) -> Result<bool> {
if !self.initialized {
return self.seek_last();
}
if !self.is_valid() {
return Ok(false);
}
if self.direction != MergeDirection::Backward {
let target = self.key().encoded().to_vec();
self.switch_to_backward(&target)?;
return Ok(self.is_valid());
}
self.advance_winner()
}
fn valid(&self) -> bool {
self.is_valid()
}
fn key(&self) -> InternalKeyRef<'_> {
debug_assert!(self.is_valid());
self.iterators[self.winner.unwrap()].key()
}
fn value_encoded(&self) -> Result<&[u8]> {
debug_assert!(self.is_valid());
self.iterators[self.winner.unwrap()].value_encoded()
}
}
pub(crate) struct SnapshotIterator<'a> {
merge_iter: KMergeIterator<'a>,
snapshot_seq_num: u64,
#[allow(dead_code)]
core: Arc<Core>,
last_key_fwd: Vec<u8>,
buffered_back_key: Vec<u8>,
buffered_back_value: Vec<u8>,
has_buffered_back: bool,
current_back_key: Vec<u8>,
current_back_value: Vec<u8>,
has_current_back: bool,
direction: MergeDirection,
initialized: bool,
}
impl SnapshotIterator<'_> {
fn new_from(core: Arc<Core>, seq_num: u64, range: InternalKeyRange) -> Result<Self> {
let snapshot = Snapshot {
core: Arc::clone(&core),
seq_num,
};
let iter_state = snapshot.collect_iter_state()?;
let merge_iter = KMergeIterator::new_from(iter_state, range);
Ok(Self {
merge_iter,
snapshot_seq_num: seq_num,
core,
last_key_fwd: Vec::new(),
buffered_back_key: Vec::new(),
buffered_back_value: Vec::new(),
has_buffered_back: false,
current_back_key: Vec::new(),
current_back_value: Vec::new(),
has_current_back: false,
direction: MergeDirection::Forward,
initialized: false,
})
}
#[inline]
fn is_visible_ref(&self, key: &InternalKeyRef<'_>) -> bool {
key.seq_num() <= self.snapshot_seq_num
}
fn skip_to_valid_forward(&mut self) -> Result<bool> {
while self.merge_iter.valid() {
let key_ref = self.merge_iter.key();
if !self.is_visible_ref(&key_ref) {
self.merge_iter.next()?;
continue;
}
let user_key = key_ref.user_key();
if user_key == self.last_key_fwd.as_slice() {
self.merge_iter.next()?;
continue;
}
self.last_key_fwd.clear();
self.last_key_fwd.extend_from_slice(user_key);
if key_ref.is_tombstone() {
self.merge_iter.next()?;
continue;
}
return Ok(true);
}
Ok(false)
}
fn skip_to_valid_backward(&mut self) -> Result<bool> {
if self.has_buffered_back {
self.has_buffered_back = false;
return self.find_latest_visible_backward();
}
if self.merge_iter.valid() {
return self.find_latest_visible_backward();
}
self.has_current_back = false;
Ok(false)
}
fn find_latest_visible_backward(&mut self) -> Result<bool> {
if !self.merge_iter.valid() {
self.has_current_back = false;
return Ok(false);
}
let first_key_ref = self.merge_iter.key();
let current_user_key: Vec<u8> = first_key_ref.user_key().to_vec();
let mut latest_key: Option<Vec<u8>> = None;
let mut latest_value: Option<Vec<u8>> = None;
if self.is_visible_ref(&first_key_ref) {
latest_key = Some(first_key_ref.encoded().to_vec());
latest_value = Some(self.merge_iter.value_encoded()?.to_vec());
}
loop {
self.merge_iter.prev()?;
if !self.merge_iter.valid() {
break;
}
let key_ref = self.merge_iter.key();
let user_key = key_ref.user_key();
if user_key != current_user_key.as_slice() {
self.buffered_back_key.clear();
self.buffered_back_key.extend_from_slice(key_ref.encoded());
self.buffered_back_value.clear();
self.buffered_back_value.extend_from_slice(self.merge_iter.value_encoded()?);
self.has_buffered_back = true;
break;
}
if self.is_visible_ref(&key_ref) {
latest_key = Some(key_ref.encoded().to_vec());
latest_value = Some(self.merge_iter.value_encoded()?.to_vec());
}
}
if let (Some(key_bytes), Some(value_bytes)) = (latest_key, latest_value) {
let key_ref = InternalKeyRef::from_encoded(&key_bytes);
if key_ref.is_tombstone() {
self.has_current_back = false;
return self.skip_to_valid_backward();
}
self.current_back_key.clear();
self.current_back_key.extend_from_slice(&key_bytes);
self.current_back_value.clear();
self.current_back_value.extend_from_slice(&value_bytes);
self.has_current_back = true;
return Ok(true);
}
self.has_current_back = false;
self.skip_to_valid_backward()
}
fn reverse_to_forward(&mut self) -> Result<bool> {
self.direction = MergeDirection::Forward;
let current_user_key = if self.has_current_back {
InternalKeyRef::from_encoded(&self.current_back_key).user_key().to_vec()
} else {
self.has_buffered_back = false;
return Ok(false);
};
self.has_current_back = false;
self.has_buffered_back = false;
self.last_key_fwd.clear();
self.last_key_fwd.extend_from_slice(¤t_user_key);
let seek_key = InternalKey::new(current_user_key, u64::MAX, InternalKeyKind::Set, u64::MAX);
self.merge_iter.seek(&seek_key.encode())?;
self.skip_to_valid_forward()
}
fn forward_to_backward(&mut self) -> Result<bool> {
self.direction = MergeDirection::Backward;
self.has_buffered_back = false;
self.has_current_back = false;
if self.merge_iter.valid() {
self.merge_iter.prev()?;
}
self.skip_to_valid_backward()
}
}
impl LSMIterator for SnapshotIterator<'_> {
fn seek(&mut self, target: &[u8]) -> Result<bool> {
self.direction = MergeDirection::Forward;
self.last_key_fwd.clear();
self.has_buffered_back = false;
self.has_current_back = false;
self.merge_iter.seek(target)?;
self.initialized = true;
self.skip_to_valid_forward()
}
fn seek_first(&mut self) -> Result<bool> {
self.direction = MergeDirection::Forward;
self.last_key_fwd.clear();
self.has_buffered_back = false;
self.has_current_back = false;
self.merge_iter.seek_first()?;
self.initialized = true;
self.skip_to_valid_forward()
}
fn seek_last(&mut self) -> Result<bool> {
self.direction = MergeDirection::Backward;
self.has_buffered_back = false;
self.has_current_back = false;
self.merge_iter.seek_last()?;
self.initialized = true;
self.skip_to_valid_backward()
}
fn next(&mut self) -> Result<bool> {
if !self.initialized {
return self.seek_first();
}
if self.direction == MergeDirection::Backward {
return self.reverse_to_forward();
}
if !self.merge_iter.valid() {
return Ok(false);
}
self.merge_iter.next()?;
self.skip_to_valid_forward()
}
fn prev(&mut self) -> Result<bool> {
if !self.initialized {
return self.seek_last();
}
if self.direction != MergeDirection::Backward {
return self.forward_to_backward();
}
if !self.merge_iter.valid() && !self.has_buffered_back {
self.has_current_back = false;
return Ok(false);
}
self.skip_to_valid_backward()
}
fn valid(&self) -> bool {
if self.direction == MergeDirection::Backward {
self.has_current_back
} else {
self.merge_iter.valid()
}
}
fn key(&self) -> InternalKeyRef<'_> {
debug_assert!(self.valid());
if self.direction == MergeDirection::Backward {
InternalKeyRef::from_encoded(&self.current_back_key)
} else {
self.merge_iter.key()
}
}
fn value_encoded(&self) -> Result<&[u8]> {
debug_assert!(self.valid());
if self.direction == MergeDirection::Backward {
Ok(&self.current_back_value)
} else {
self.merge_iter.value_encoded()
}
}
}
pub struct BPlusTreeIteratorWithGuard<'a> {
iter: BPlusTreeIterator<'a, File>,
#[allow(dead_code)]
_guard: RwLockReadGuard<'a, DiskBPlusTree>,
}
impl<'a> BPlusTreeIteratorWithGuard<'a> {
pub(crate) fn new(versioned_index: &'a parking_lot::RwLock<DiskBPlusTree>) -> Result<Self> {
let guard = versioned_index.read();
let tree_ref: &'a DiskBPlusTree = unsafe { &*(&*guard as *const DiskBPlusTree) };
let iter = tree_ref.internal_iterator();
Ok(Self {
iter,
_guard: guard,
})
}
}
impl LSMIterator for BPlusTreeIteratorWithGuard<'_> {
fn seek(&mut self, target: &[u8]) -> Result<bool> {
self.iter.seek(target)
}
fn seek_first(&mut self) -> Result<bool> {
self.iter.seek_first()
}
fn seek_last(&mut self) -> Result<bool> {
self.iter.seek_last()
}
fn next(&mut self) -> Result<bool> {
self.iter.next()
}
fn prev(&mut self) -> Result<bool> {
self.iter.prev()
}
fn valid(&self) -> bool {
self.iter.valid()
}
fn key(&self) -> InternalKeyRef<'_> {
self.iter.key()
}
fn value_encoded(&self) -> Result<&[u8]> {
self.iter.value_encoded()
}
}
#[derive(Clone)]
struct BufferedEntry {
key: Vec<u8>,
value: Vec<u8>,
}
pub struct HistoryIterator<'a> {
inner: KMergeIterator<'a>,
snapshot_seq_num: u64,
include_tombstones: bool,
direction: MergeDirection,
initialized: bool,
lower_bound: Option<Vec<u8>>,
upper_bound: Option<Vec<u8>>,
current_user_key: Vec<u8>,
first_visible_seen: bool,
latest_is_hard_delete: bool,
barrier_seen: bool,
backward_buffer: Vec<BufferedEntry>,
backward_buffer_index: Option<usize>,
ts_range: Option<(u64, u64)>, limit: Option<usize>,
entries_returned: usize,
limit_reached: bool,
}
impl<'a> HistoryIterator<'a> {
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
merge_iter: KMergeIterator<'a>,
seq_num: u64,
include_tombstones: bool,
lower: Option<&[u8]>,
upper: Option<&[u8]>,
ts_range: Option<(u64, u64)>,
limit: Option<usize>,
) -> Self {
Self {
inner: merge_iter,
snapshot_seq_num: seq_num,
include_tombstones,
direction: MergeDirection::Forward,
initialized: false,
lower_bound: lower.map(|b| b.to_vec()),
upper_bound: upper.map(|b| b.to_vec()),
current_user_key: Vec::new(),
first_visible_seen: false,
latest_is_hard_delete: false,
barrier_seen: false,
backward_buffer: Vec::new(),
backward_buffer_index: None,
ts_range,
limit,
entries_returned: 0,
limit_reached: false,
}
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn new_lsm(
seq_num: u64,
iter_state: IterState,
range: InternalKeyRange,
include_tombstones: bool,
ts_range: Option<(u64, u64)>,
limit: Option<usize>,
lower: Option<&[u8]>,
upper: Option<&[u8]>,
) -> Self {
let inner = if ts_range.is_some() {
KMergeIterator::new_for_history(iter_state, range, ts_range)
} else {
KMergeIterator::new_from(iter_state, range)
};
Self::new(inner, seq_num, include_tombstones, lower, upper, ts_range, limit)
}
fn reset_forward_state(&mut self) {
self.current_user_key.clear();
self.first_visible_seen = false;
self.latest_is_hard_delete = false;
self.barrier_seen = false;
}
fn clear_backward_buffer(&mut self) {
self.backward_buffer.clear();
self.backward_buffer_index = None;
}
fn reset_all_state(&mut self) {
self.reset_forward_state();
self.clear_backward_buffer();
self.entries_returned = 0;
self.limit_reached = false;
}
fn inner_valid(&self) -> bool {
self.inner.valid()
}
fn inner_key(&self) -> InternalKeyRef<'_> {
self.inner.key()
}
fn inner_value(&self) -> Result<&[u8]> {
self.inner.value_encoded()
}
fn inner_next(&mut self) -> Result<bool> {
self.inner.next()
}
fn inner_prev(&mut self) -> Result<bool> {
self.inner.prev()
}
fn skip_to_next_user_key(&mut self) -> Result<bool> {
let current = self.current_user_key.clone();
while self.inner_valid() {
if self.inner_key().user_key() != current.as_slice() {
return Ok(true);
}
self.inner_next()?;
}
Ok(false)
}
fn advance_to_next_user_key(&mut self) -> Result<bool> {
let ts_end = match self.ts_range {
Some((_, end)) => end,
None => return self.skip_to_next_user_key(),
};
let current = self.current_user_key.clone();
while self.inner_valid() {
let next_key_vec = self.inner_key().user_key().to_vec();
if next_key_vec != current {
let seek_key =
InternalKey::new(next_key_vec, u64::MAX, InternalKeyKind::Set, ts_end);
self.inner.seek(&seek_key.encode())?;
return Ok(self.inner_valid());
}
self.inner_next()?;
}
Ok(false)
}
fn within_upper_bound(&self) -> bool {
if let Some(ref upper) = self.upper_bound {
if self.inner_valid() {
self.inner_key().user_key() < upper.as_slice()
} else {
false
}
} else {
true
}
}
fn user_key_within_lower_bound(&self, user_key: &[u8]) -> bool {
match &self.lower_bound {
Some(lower) => user_key >= lower.as_slice(),
None => true,
}
}
fn user_key_within_upper_bound(&self, user_key: &[u8]) -> bool {
match &self.upper_bound {
Some(upper) => user_key < upper.as_slice(),
None => true,
}
}
fn skip_to_valid_forward(&mut self) -> Result<bool> {
while self.inner_valid() {
if let Some(limit) = self.limit {
if self.entries_returned >= limit {
self.limit_reached = true;
return Ok(false);
}
}
if !self.within_upper_bound() {
return Ok(false);
}
let (user_key_vec, seq_num, timestamp, is_hard_delete, is_replace, is_tombstone) = {
let key_ref = self.inner_key();
(
key_ref.user_key().to_vec(),
key_ref.seq_num(),
key_ref.timestamp(),
key_ref.is_hard_delete_marker(),
key_ref.is_replace(),
key_ref.is_tombstone(),
)
};
if !self.user_key_within_lower_bound(&user_key_vec) {
self.inner_next()?;
continue;
}
if user_key_vec != self.current_user_key {
self.current_user_key = user_key_vec;
self.first_visible_seen = false;
self.latest_is_hard_delete = false;
self.barrier_seen = false;
}
if seq_num > self.snapshot_seq_num {
self.inner_next()?;
continue;
}
if let Some((ts_start, ts_end)) = self.ts_range {
if timestamp > ts_end {
self.inner_next()?;
continue;
}
if timestamp < ts_start {
if !self.advance_to_next_user_key()? {
return Ok(false);
}
continue;
}
}
if !self.first_visible_seen {
self.first_visible_seen = true;
if is_hard_delete {
self.latest_is_hard_delete = true;
}
}
if self.latest_is_hard_delete {
self.inner_next()?;
continue;
}
if self.barrier_seen {
self.inner_next()?;
continue;
}
if is_hard_delete {
self.barrier_seen = true;
self.inner_next()?;
continue;
}
if is_replace {
self.barrier_seen = true;
}
if !self.include_tombstones && is_tombstone {
self.inner_next()?;
continue;
}
self.entries_returned += 1;
return Ok(true);
}
Ok(false)
}
fn collect_user_key_backward(&mut self) -> Result<bool> {
self.backward_buffer.clear();
if !self.inner_valid() {
return Ok(false);
}
let user_key = self.inner_key().user_key().to_vec();
if !self.user_key_within_lower_bound(&user_key) {
return Ok(false);
}
if !self.user_key_within_upper_bound(&user_key) {
while self.inner_valid() && self.inner_key().user_key() == user_key.as_slice() {
self.inner_prev()?;
}
return self.collect_user_key_backward();
}
struct VersionInfo {
is_hard_delete: bool,
is_replace: bool,
is_tombstone: bool,
encoded_key: Vec<u8>,
value: Vec<u8>,
}
let mut versions: Vec<VersionInfo> = Vec::new();
while self.inner_valid() {
let key_ref = self.inner_key();
if key_ref.user_key() != user_key.as_slice() {
break;
}
let seq_num = key_ref.seq_num();
let timestamp = key_ref.timestamp();
let visible = seq_num <= self.snapshot_seq_num;
let in_ts_range = match self.ts_range {
Some((ts_start, ts_end)) => timestamp >= ts_start && timestamp <= ts_end,
None => true,
};
if visible && in_ts_range {
versions.push(VersionInfo {
is_hard_delete: key_ref.is_hard_delete_marker(),
is_replace: key_ref.is_replace(),
is_tombstone: key_ref.is_tombstone(),
encoded_key: key_ref.encoded().to_vec(),
value: self.inner_value()?.to_vec(),
});
}
self.inner_prev()?;
}
if versions.is_empty() {
return Ok(false);
}
let latest = versions.last().unwrap();
if latest.is_hard_delete {
return Ok(false);
}
let mut barrier_idx: Option<usize> = None;
let mut barrier_is_hard_delete = false;
for i in (0..versions.len()).rev() {
if versions[i].is_hard_delete {
barrier_idx = Some(i);
barrier_is_hard_delete = true;
break;
}
if versions[i].is_replace {
barrier_idx = Some(i);
barrier_is_hard_delete = false;
break;
}
}
let valid_start_idx = match barrier_idx {
Some(idx) if barrier_is_hard_delete => idx + 1, Some(idx) => idx, None => 0, };
for v in versions.into_iter().skip(valid_start_idx) {
if v.is_hard_delete {
continue;
}
if !self.include_tombstones && v.is_tombstone {
continue;
}
self.backward_buffer.push(BufferedEntry {
key: v.encoded_key,
value: v.value,
});
}
if self.backward_buffer.is_empty() {
return Ok(false);
}
if let Some(limit) = self.limit {
let remaining = limit.saturating_sub(self.entries_returned);
if remaining == 0 {
self.backward_buffer.clear();
self.limit_reached = true;
return Ok(false);
}
if self.backward_buffer.len() > remaining {
self.backward_buffer.truncate(remaining);
}
}
self.entries_returned += self.backward_buffer.len();
self.backward_buffer_index = Some(0);
Ok(true)
}
fn advance_backward(&mut self) -> Result<bool> {
if let Some(idx) = self.backward_buffer_index {
if idx + 1 < self.backward_buffer.len() {
self.backward_buffer_index = Some(idx + 1);
return Ok(true);
}
}
self.collect_user_key_backward()
}
fn buffered_key(&self) -> InternalKeyRef<'_> {
let idx = self.backward_buffer_index.unwrap();
InternalKeyRef::from_encoded(&self.backward_buffer[idx].key)
}
fn buffered_value(&self) -> &[u8] {
let idx = self.backward_buffer_index.unwrap();
&self.backward_buffer[idx].value
}
fn has_buffered_entry(&self) -> bool {
matches!(self.backward_buffer_index, Some(idx) if idx < self.backward_buffer.len())
}
fn reverse_to_forward(&mut self) -> Result<bool> {
self.direction = MergeDirection::Forward;
self.reset_forward_state();
if !self.has_buffered_entry() {
self.clear_backward_buffer();
return Ok(false);
}
let current_internal_key = self.buffered_key().encoded().to_vec();
self.clear_backward_buffer();
self.inner.seek(¤t_internal_key)?;
if !self.inner_valid() {
return Ok(false);
}
self.inner_next()?;
self.skip_to_valid_forward()
}
fn forward_to_backward(&mut self) -> Result<bool> {
self.direction = MergeDirection::Backward;
self.clear_backward_buffer();
if !self.inner_valid() {
return Ok(false);
}
self.inner_prev()?;
self.collect_user_key_backward()
}
}
impl LSMIterator for HistoryIterator<'_> {
fn seek(&mut self, target: &[u8]) -> Result<bool> {
self.direction = MergeDirection::Forward;
self.reset_all_state();
self.inner.seek(target)?;
self.initialized = true;
self.skip_to_valid_forward()
}
fn seek_first(&mut self) -> Result<bool> {
self.direction = MergeDirection::Forward;
self.reset_all_state();
if self.ts_range.is_some() {
let ts = self.ts_range.map(|(_, end)| end).unwrap_or(u64::MAX);
let seek_key = InternalKey::new(
self.lower_bound.clone().unwrap_or_default(),
u64::MAX,
InternalKeyKind::Set,
ts,
);
self.inner.seek(&seek_key.encode())?;
} else if let Some(ref lower) = self.lower_bound {
let seek_key =
InternalKey::new(lower.clone(), u64::MAX, InternalKeyKind::Set, u64::MAX);
self.inner.seek(&seek_key.encode())?;
} else {
self.inner.seek_first()?;
}
self.initialized = true;
self.skip_to_valid_forward()
}
fn seek_last(&mut self) -> Result<bool> {
self.direction = MergeDirection::Backward;
self.reset_all_state();
self.inner.seek_last()?;
self.initialized = true;
self.collect_user_key_backward()
}
fn next(&mut self) -> Result<bool> {
if !self.initialized {
return self.seek_first();
}
if self.direction == MergeDirection::Backward {
return self.reverse_to_forward();
}
if !self.inner_valid() {
return Ok(false);
}
self.inner_next()?;
self.skip_to_valid_forward()
}
fn prev(&mut self) -> Result<bool> {
if !self.initialized {
return self.seek_last();
}
if self.direction != MergeDirection::Backward {
return self.forward_to_backward();
}
if !self.has_buffered_entry() && !self.inner_valid() {
return Ok(false);
}
self.advance_backward()
}
fn valid(&self) -> bool {
if self.limit_reached {
return false;
}
match self.direction {
MergeDirection::Forward => self.inner_valid() && self.within_upper_bound(),
MergeDirection::Backward => self.has_buffered_entry(),
}
}
fn key(&self) -> InternalKeyRef<'_> {
debug_assert!(self.valid());
match self.direction {
MergeDirection::Forward => self.inner_key(),
MergeDirection::Backward => self.buffered_key(),
}
}
fn value_encoded(&self) -> Result<&[u8]> {
debug_assert!(self.valid());
match self.direction {
MergeDirection::Forward => self.inner_value(),
MergeDirection::Backward => Ok(self.buffered_value()),
}
}
}
#[cfg(test)]
mod tests {
use super::SnapshotTracker;
#[test]
fn test_snapshot_tracker_ordering() {
let tracker = SnapshotTracker::new();
tracker.register(100);
tracker.register(50);
tracker.register(200);
tracker.register(75);
tracker.register(150);
let snapshots = tracker.get_all_snapshots();
assert_eq!(snapshots, vec![50, 75, 100, 150, 200]);
tracker.unregister(100);
tracker.unregister(50);
let snapshots = tracker.get_all_snapshots();
assert_eq!(snapshots, vec![75, 150, 200]);
tracker.register(25);
tracker.register(300);
let snapshots = tracker.get_all_snapshots();
assert_eq!(snapshots, vec![25, 75, 150, 200, 300]);
}
#[test]
fn test_snapshot_tracker_empty() {
let tracker = SnapshotTracker::new();
assert!(tracker.get_all_snapshots().is_empty());
}
#[test]
fn test_snapshot_tracker_clone_shares_state() {
let tracker1 = SnapshotTracker::new();
tracker1.register(100);
let tracker2 = tracker1.clone();
tracker2.register(50);
assert_eq!(tracker1.get_all_snapshots(), vec![50, 100]);
assert_eq!(tracker2.get_all_snapshots(), vec![50, 100]);
}
}