pub enum AnyTree {
Standard(Tree),
Blob(BlobTree),
}Expand description
Variants§
Standard(Tree)
Standard LSM-tree, see Tree
Blob(BlobTree)
Key-value separated LSM-tree, see BlobTree
Implementations§
Source§impl AnyTree
impl AnyTree
Sourcepub fn close(self) -> TreeClose
pub fn close(self) -> TreeClose
Gives up this handle and returns the signal of the tree being closed;
see Tree::close.
Sourcepub fn start_multi_get<K: Into<UserKey>>(
&self,
keys: impl IntoIterator<Item = K>,
seqno: SeqNo,
) -> Result<Step>
pub fn start_multi_get<K: Into<UserKey>>( &self, keys: impl IntoIterator<Item = K>, seqno: SeqNo, ) -> Result<Step>
Starts a multi-get of keys at seqno that its caller drives: see
Tree::start_multi_get.
§Errors
Returns crate::Error::SnapshotBelowRetention when seqno is below
what the tree retains.
Source§impl AnyTree
impl AnyTree
Sourcepub fn ingestion(&self) -> Result<AnyIngestion<'_>>
pub fn ingestion(&self) -> Result<AnyIngestion<'_>>
Starts an ingestion for any tree type (standard or blob).
§Errors
Will return Err if an IO error occurs.
Sourcepub fn columnar_scan<R: RangeBounds<UserKey>>(
&self,
projection: impl Into<Projection>,
predicate: Option<&ColumnRangePredicate>,
seqno: SeqNo,
range: R,
) -> Result<ColumnarScan>
pub fn columnar_scan<R: RangeBounds<UserKey>>( &self, projection: impl Into<Projection>, predicate: Option<&ColumnRangePredicate>, seqno: SeqNo, range: R, ) -> Result<ColumnarScan>
Runs a projected columnar scan across the tree.
Delegates to Tree::columnar_scan on a
standard tree and to BlobTree::columnar_scan
on a blob tree: reads the memtables and every table intersecting
range at seqno, and yields projected
ColumnBatches in key order, one
row per key, its newest visible version. See
Tree::columnar_scan for the full contract.
§Errors
As Tree::columnar_scan and
BlobTree::columnar_scan.
§Examples
use lsm_tree::table::columnar::{Column, TypeTag, entries_to_column_batch};
use lsm_tree::{AnyTree, Config, InternalValue, SeqNo, ValueType};
let folder = tempfile::tempdir()?;
let any = Config::new(folder, Default::default(), Default::default()).open()?;
if let AnyTree::Standard(tree) = &any {
tree.update_runtime_config(|cfg| cfg.columnar = true)?;
}
// Ingest one row whose value is a single fixed-4 sub-column (id 3).
let mut batch = entries_to_column_batch(&[InternalValue::from_components(
b"k0".to_vec(),
b"x".to_vec(),
0,
ValueType::Value,
)])?;
batch.columns.pop();
batch.columns.push(Column {
column_id: 3,
type_tag: TypeTag::Fixed(4),
validity: None,
data: vec![1, 0, 0, 0].into(),
});
let mut ingestion = any.ingestion()?;
ingestion.write_columnar_batch(&batch)?;
ingestion.finish()?;
// Scan projecting only sub-column 3 across the whole tree.
let mut rows = 0;
for batch in any.columnar_scan(&[3], None, SeqNo::MAX, ..)? {
rows += batch?.row_count;
}
assert_eq!(rows, 1);Trait Implementations§
Source§impl AbstractTree for AnyTree
impl AbstractTree for AnyTree
Source§fn table_file_cache_size(&self) -> usize
fn table_file_cache_size(&self) -> usize
Source§fn storage_stats(&self) -> Result<StorageStats>
fn storage_stats(&self) -> Result<StorageStats>
StorageStats::estimated_remaining_entries). Read moreSource§fn level_segment_stats(&self) -> Result<Vec<LevelStats>>
fn level_segment_stats(&self) -> Result<Vec<LevelStats>>
Source§fn compaction_debt(&self, strategy: &dyn CompactionStrategy) -> u64
fn compaction_debt(&self, strategy: &dyn CompactionStrategy) -> u64
strategy: on-disk data above
its level’s target that must eventually be rewritten downward (a RocksDB
estimate-pending-compaction-bytes analog), a compaction-debt signal for a
scheduler / tiering consumer. Read moreSource§fn write_backpressure(&self, strategy: &dyn CompactionStrategy) -> Backpressure
fn write_backpressure(&self, strategy: &dyn CompactionStrategy) -> Backpressure
RuntimeConfig::backpressure
thresholds. Read moreSource§fn write_backpressure_for(
&self,
strategy: &dyn CompactionStrategy,
bytes: u64,
) -> Backpressure
fn write_backpressure_for( &self, strategy: &dyn CompactionStrategy, bytes: u64, ) -> Backpressure
bytes: write_backpressure,
except that a slowdown on a tree with a write rate limit (see
Config::write_rate_limit) debits
bytes from the tree’s write limiter and suggests waiting until they,
and every byte debited before them, are paid off at its rate. Writes
honouring it are then bounded by the rate in bytes per second, large
and small alike, however many writers share the limiter. Outside the
slowdown tier nothing is debited. Read moreSource§fn write_rate_limiter(&self) -> Arc<RateLimiter> ⓘ
fn write_rate_limiter(&self) -> Arc<RateLimiter> ⓘ
Config::write_rate_limiter, else
the tree’s own. Retune it live with
RateLimiter::set_rate;
0 turns byte pacing off.Source§fn write_admission(&self) -> Result<()>
fn write_admission(&self) -> Result<()>
Ok(()) if a write may proceed, or
Error::StorageFull if the tree is
over budget and should be treated as read-only. Read moreSource§fn is_read_only(&self) -> bool
fn is_read_only(&self) -> bool
true when the admission gate is currently closed (see
write_admission). Convenience for callers that
want a boolean rather than a Result. Always false unless admission
control is enabled and the tree is over budget. Read moreSource§fn verify_checksum(&self) -> BlockVerifyReportwhere
Self: Sized,
fn verify_checksum(&self) -> BlockVerifyReportwhere
Self: Sized,
Source§fn verify_checksum_with(&self, options: &VerifyOptions) -> BlockVerifyReportwhere
Self: Sized,
fn verify_checksum_with(&self, options: &VerifyOptions) -> BlockVerifyReportwhere
Self: Sized,
Self::verify_checksum but with configurable parallelism and
I/O throttle (see VerifyOptions).Source§fn create_checkpoint(&self, target_path: &Path) -> Result<CheckpointInfo>
fn create_checkpoint(&self, target_path: &Path) -> Result<CheckpointInfo>
target_path for point-in-time recovery (PITR) backup. Read moreSource§fn pin(&self) -> PinnedVersion
fn pin(&self) -> PinnedVersion
PinnedVersion holding the sealed memtables,
tables, blob files and dictionaries as they are now. Read moreSource§fn acknowledge_repair_report(&self, id: u128) -> Result<bool>
fn acknowledge_repair_report(&self, id: u128) -> Result<bool>
RepairReport::id, installing a version
that no longer carries it: no later
Config::open_or_repair hands it out. Read moreSource§fn flush_active_memtable(&self, gc_watermark: SeqNo) -> Result<()>
fn flush_active_memtable(&self, gc_watermark: SeqNo) -> Result<()>
Source§fn persist_flushes(&self) -> Result<()>
fn persist_flushes(&self) -> Result<()>
FlushDurability::Deferred:
the tables and blob files those flushes wrote are synced, then their
folders, then the manifest is written. Once it returns Ok a caller
may drop its own log up to the writes those flushes held; under
SyncMode::Barrier after
sync_devices as well. A no-op when nothing is
pending, and under FlushDurability::Synced
every flush is durable when it returns. Read moreSource§fn sync_devices(&self) -> Result<()>
fn sync_devices(&self) -> Result<()>
Source§fn flush(
&self,
lock: &MutexGuard<'_, ()>,
gc_watermark: SeqNo,
) -> Result<Option<u64>>
fn flush( &self, lock: &MutexGuard<'_, ()>, gc_watermark: SeqNo, ) -> Result<Option<u64>>
Source§fn iter(
&self,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Box<dyn DoubleEndedIterator<Item = IterGuardImpl> + Send + 'static>
fn iter( &self, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Box<dyn DoubleEndedIterator<Item = IterGuardImpl> + Send + 'static>
Source§fn prefix<K: AsRef<[u8]>>(
&self,
prefix: K,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Box<dyn DoubleEndedIterator<Item = IterGuardImpl> + Send + 'static>
fn prefix<K: AsRef<[u8]>>( &self, prefix: K, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Box<dyn DoubleEndedIterator<Item = IterGuardImpl> + Send + 'static>
Source§fn range<K: AsRef<[u8]>, R: RangeBounds<K>>(
&self,
range: R,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Box<dyn DoubleEndedIterator<Item = IterGuardImpl> + Send + 'static>
fn range<K: AsRef<[u8]>, R: RangeBounds<K>>( &self, range: R, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Box<dyn DoubleEndedIterator<Item = IterGuardImpl> + Send + 'static>
Source§fn range_seekable<K: AsRef<[u8]>, R: RangeBounds<K>>(
&self,
range: R,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Box<dyn SeekableGuardIter + 'static>
fn range_seekable<K: AsRef<[u8]>, R: RangeBounds<K>>( &self, range: R, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Box<dyn SeekableGuardIter + 'static>
Source§fn batch_range_scan<K: AsRef<[u8]>, R: RangeBounds<K> + 'static, I: IntoIterator<Item = R>>(
&self,
intervals: I,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Box<dyn Iterator<Item = IterGuardImpl> + Send + 'static>
fn batch_range_scan<K: AsRef<[u8]>, R: RangeBounds<K> + 'static, I: IntoIterator<Item = R>>( &self, intervals: I, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Box<dyn Iterator<Item = IterGuardImpl> + Send + 'static>
Source§fn tombstone_count(&self) -> u64
fn tombstone_count(&self) -> u64
Source§fn weak_tombstone_count(&self) -> u64
fn weak_tombstone_count(&self) -> u64
Source§fn weak_tombstone_reclaimable_count(&self) -> u64
fn weak_tombstone_reclaimable_count(&self) -> u64
Source§fn major_compact(
&self,
target_size: u64,
gc_watermark: SeqNo,
) -> Result<CompactionResult>
fn major_compact( &self, target_size: u64, gc_watermark: SeqNo, ) -> Result<CompactionResult>
Source§fn stale_blob_bytes(&self) -> u64
fn stale_blob_bytes(&self) -> u64
Source§fn filter_size(&self) -> u64
fn filter_size(&self) -> u64
Source§fn pinned_filter_size(&self) -> usize
fn pinned_filter_size(&self) -> usize
Source§fn filter_memory(&self) -> FilterMemory
fn filter_memory(&self) -> FilterMemory
FilterAdvisor
budget. Read moreSource§fn pinned_block_index_size(&self) -> usize
fn pinned_block_index_size(&self) -> usize
Source§fn cache_stats(&self) -> CacheStats
fn cache_stats(&self) -> CacheStats
CacheStats snapshot of block-cache
effectiveness (cumulative hit / miss counts and rate) and occupancy
(current size against capacity). Read moreSource§fn get_flush_lock(&self) -> MutexGuard<'_, ()>
fn get_flush_lock(&self) -> MutexGuard<'_, ()>
Tree::flush.Source§fn flush_to_tables(
&self,
stream: impl Iterator<Item = Result<InternalValue>>,
) -> Result<Option<(Vec<Table>, Option<Vec<BlobFile>>, WritePin)>>
fn flush_to_tables( &self, stream: impl Iterator<Item = Result<InternalValue>>, ) -> Result<Option<(Vec<Table>, Option<Vec<BlobFile>>, WritePin)>>
Source§fn register_tables(
&self,
tables: &[Table],
blob_files: Option<&[BlobFile]>,
frag_map: Option<FragmentationMap>,
sealed_memtables_to_delete: &[MemtableId],
gc_watermark: SeqNo,
collected_below_watermark: bool,
) -> Result<()>
fn register_tables( &self, tables: &[Table], blob_files: Option<&[BlobFile]>, frag_map: Option<FragmentationMap>, sealed_memtables_to_delete: &[MemtableId], gc_watermark: SeqNo, collected_below_watermark: bool, ) -> Result<()>
Source§fn clear_active_memtable(&self)
fn clear_active_memtable(&self)
Source§fn sealed_memtable_count(&self) -> usize
fn sealed_memtable_count(&self) -> usize
Source§fn compact(
&self,
strategy: Arc<dyn CompactionStrategy>,
gc_watermark: SeqNo,
) -> Result<CompactionResult>
fn compact( &self, strategy: Arc<dyn CompactionStrategy>, gc_watermark: SeqNo, ) -> Result<CompactionResult>
Source§fn get_next_table_id(&self) -> TableId
fn get_next_table_id(&self) -> TableId
Source§fn tree_config(&self) -> &Config
fn tree_config(&self) -> &Config
Source§fn get_highest_seqno(&self) -> Option<SeqNo>
fn get_highest_seqno(&self) -> Option<SeqNo>
Source§fn table_count(&self) -> usize
fn table_count(&self) -> usize
Source§fn level_table_count(&self, idx: usize) -> Option<usize>
fn level_table_count(&self, idx: usize) -> Option<usize>
levels[idx]. Read moreSource§fn l0_run_count(&self) -> usize
fn l0_run_count(&self) -> usize
Source§fn blob_file_count(&self) -> usize
fn blob_file_count(&self) -> usize
Source§fn approximate_len(&self) -> usize
fn approximate_len(&self) -> usize
Source§fn disk_space(&self) -> u64
fn disk_space(&self) -> u64
Source§fn approximate_range_stats<K: AsRef<[u8]>, R: RangeBounds<K>>(
&self,
range: R,
seqno: SeqNo,
) -> Result<ApproximateRangeStats>
fn approximate_range_stats<K: AsRef<[u8]>, R: RangeBounds<K>>( &self, range: R, seqno: SeqNo, ) -> Result<ApproximateRangeStats>
range at
seqno, WITHOUT reading any data block. Read moreSource§fn approximate_range_cardinality<K: AsRef<[u8]>, R: RangeBounds<K>>(
&self,
range: R,
seqno: SeqNo,
) -> Result<RangeCardinality>
fn approximate_range_cardinality<K: AsRef<[u8]>, R: RangeBounds<K>>( &self, range: R, seqno: SeqNo, ) -> Result<RangeCardinality>
range at seqno,
WITHOUT reading any data block. Read moreSource§fn get_highest_memtable_seqno(&self) -> Option<SeqNo>
fn get_highest_memtable_seqno(&self) -> Option<SeqNo>
Source§fn get_highest_persisted_seqno(&self) -> Option<SeqNo>
fn get_highest_persisted_seqno(&self) -> Option<SeqNo>
Source§fn oldest_retained_seqno(&self) -> SeqNo
fn oldest_retained_seqno(&self) -> SeqNo
Source§fn retention_floor(&self) -> SeqNo
fn retention_floor(&self) -> SeqNo
oldest_retained_seqno. Read moreSource§fn lower_retention_floor(&self, floor: SeqNo) -> Result<()>
fn lower_retention_floor(&self, floor: SeqNo) -> Result<()>
floor, so snapshots above it
are served again, now and after a reopen. Read moreSource§fn compaction_rate_limiter(&self) -> Arc<RateLimiter> ⓘ
fn compaction_rate_limiter(&self) -> Arc<RateLimiter> ⓘ
Config::compaction_rate_limiter,
which other trees may share, or the tree’s own built from
Config::compaction_rate_limit. Read moreSource§fn len(
&self,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Result<usize>
fn len( &self, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Result<usize>
Source§fn is_empty(
&self,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Result<bool>
fn is_empty( &self, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Result<bool>
true if the tree is empty. Read moreSource§fn first_key_value(
&self,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Option<IterGuardImpl>
fn first_key_value( &self, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Option<IterGuardImpl>
Source§fn last_key_value(
&self,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Option<IterGuardImpl>
fn last_key_value( &self, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Option<IterGuardImpl>
Source§fn size_of<K: AsRef<[u8]>>(&self, key: K, seqno: SeqNo) -> Result<Option<u32>>
fn size_of<K: AsRef<[u8]>>(&self, key: K, seqno: SeqNo) -> Result<Option<u32>>
Source§fn get<K: AsRef<[u8]>>(&self, key: K, seqno: SeqNo) -> Result<Option<UserValue>>
fn get<K: AsRef<[u8]>>(&self, key: K, seqno: SeqNo) -> Result<Option<UserValue>>
Source§fn get_pinned<K: AsRef<[u8]>>(
&self,
key: K,
seqno: SeqNo,
) -> Result<Option<PinnableSlice>>
fn get_pinned<K: AsRef<[u8]>>( &self, key: K, seqno: SeqNo, ) -> Result<Option<PinnableSlice>>
PinnableSlice. Read moreSource§fn contains_key<K: AsRef<[u8]>>(&self, key: K, seqno: SeqNo) -> Result<bool>
fn contains_key<K: AsRef<[u8]>>(&self, key: K, seqno: SeqNo) -> Result<bool>
true if the tree contains the specified key. Read moreSource§fn contains_prefix<K: AsRef<[u8]>>(
&self,
prefix: K,
seqno: SeqNo,
index: Option<(Arc<Memtable>, SeqNo)>,
) -> Result<bool>
fn contains_prefix<K: AsRef<[u8]>>( &self, prefix: K, seqno: SeqNo, index: Option<(Arc<Memtable>, SeqNo)>, ) -> Result<bool>
true if the tree contains any key with the given prefix. Read moreSource§fn multi_get<K: AsRef<[u8]>>(
&self,
keys: impl IntoIterator<Item = K>,
seqno: SeqNo,
) -> Result<Vec<Option<UserValue>>>
fn multi_get<K: AsRef<[u8]>>( &self, keys: impl IntoIterator<Item = K>, seqno: SeqNo, ) -> Result<Vec<Option<UserValue>>>
Source§fn apply_batch(&self, batch: WriteBatch, seqno: SeqNo) -> Result<(u64, u64)>
fn apply_batch(&self, batch: WriteBatch, seqno: SeqNo) -> Result<(u64, u64)>
WriteBatch with the given sequence number. Read moreSource§fn insert<K: Into<UserKey>, V: Into<UserValue>>(
&self,
key: K,
value: V,
seqno: SeqNo,
) -> (u64, u64)
fn insert<K: Into<UserKey>, V: Into<UserValue>>( &self, key: K, value: V, seqno: SeqNo, ) -> (u64, u64)
Source§fn try_insert<K: Into<UserKey>, V: Into<UserValue>>(
&self,
key: K,
value: V,
seqno: SeqNo,
) -> Result<(u64, u64)>
fn try_insert<K: Into<UserKey>, V: Into<UserValue>>( &self, key: K, value: V, seqno: SeqNo, ) -> Result<(u64, u64)>
insert: consults
write_admission first and declines with
Error::StorageFull when the tree is over
budget, otherwise inserts and returns the same (added_bytes, memtable_size) tuple. This is the write entry a space-aware caller uses
so over-budget writes are refused up front rather than failing a flush
later; bare insert stays infallible for callers that
do not opt into admission control. Read moreSource§fn try_merge<K: Into<UserKey>, V: Into<UserValue>>(
&self,
key: K,
operand: V,
seqno: SeqNo,
) -> Result<(u64, u64)>
fn try_merge<K: Into<UserKey>, V: Into<UserValue>>( &self, key: K, operand: V, seqno: SeqNo, ) -> Result<(u64, u64)>
Source§fn try_remove_range<K: Into<UserKey>>(
&self,
start: K,
end: K,
seqno: SeqNo,
) -> Result<u64>
fn try_remove_range<K: Into<UserKey>>( &self, start: K, end: K, seqno: SeqNo, ) -> Result<u64>
Source§fn remove<K: Into<UserKey>>(&self, key: K, seqno: SeqNo) -> (u64, u64)
fn remove<K: Into<UserKey>>(&self, key: K, seqno: SeqNo) -> (u64, u64)
Source§fn merge<K: Into<UserKey>, V: Into<UserValue>>(
&self,
key: K,
operand: V,
seqno: SeqNo,
) -> (u64, u64)
fn merge<K: Into<UserKey>, V: Into<UserValue>>( &self, key: K, operand: V, seqno: SeqNo, ) -> (u64, u64)
Auto Trait Implementations§
impl !RefUnwindSafe for AnyTree
impl !UnwindSafe for AnyTree
impl Freeze for AnyTree
impl Send for AnyTree
impl Sync for AnyTree
impl Unpin for AnyTree
impl UnsafeUnpin for AnyTree
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> StorageStatistics for Twhere
T: AbstractTree + ?Sized,
impl<T> StorageStatistics for Twhere
T: AbstractTree + ?Sized,
Source§fn storage_stats(&self) -> Result<StorageStats, Error>
fn storage_stats(&self) -> Result<StorageStats, Error>
StorageStatus. See
StorageStats::estimated_remaining_entries for a budget projection. Read moreSource§fn level_segment_stats(&self) -> Result<Vec<LevelStats>, Error>
fn level_segment_stats(&self) -> Result<Vec<LevelStats>, Error>
Source§fn compaction_debt(&self, strategy: &dyn CompactionStrategy) -> u64
fn compaction_debt(&self, strategy: &dyn CompactionStrategy) -> u64
strategy: on-disk data above
its level’s target that must eventually be rewritten downward (a RocksDB
estimate-pending-compaction-bytes analog), a compaction-debt signal for a
scheduler / tiering consumer. Read moreSource§fn cache_stats(&self) -> CacheStats
fn cache_stats(&self) -> CacheStats
CacheStats snapshot of block-cache
effectiveness (cumulative hit / miss counts and rate) and occupancy
(current size against capacity). Read more