2024-01-16 16:30:01 +08:00
|
|
|
mod leveled;
|
2024-01-17 15:42:33 +08:00
|
|
|
mod simple_leveled;
|
2024-01-16 16:30:01 +08:00
|
|
|
mod tiered;
|
|
|
|
|
|
2024-01-10 14:25:23 +08:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
|
|
use anyhow::Result;
|
2024-01-18 14:50:12 +08:00
|
|
|
pub use leveled::{LeveledCompactionController, LeveledCompactionOptions, LeveledCompactionTask};
|
2024-01-17 15:42:33 +08:00
|
|
|
pub use simple_leveled::{
|
|
|
|
|
SimpleLeveledCompactionController, SimpleLeveledCompactionOptions, SimpleLeveledCompactionTask,
|
|
|
|
|
};
|
2024-01-17 14:51:15 +08:00
|
|
|
pub use tiered::{TieredCompactionController, TieredCompactionOptions, TieredCompactionTask};
|
2024-01-16 16:30:01 +08:00
|
|
|
|
|
|
|
|
use crate::iterators::merge_iterator::MergeIterator;
|
|
|
|
|
use crate::iterators::StorageIterator;
|
2024-01-18 17:51:24 +08:00
|
|
|
use crate::lsm_storage::LsmStorageInner;
|
2024-01-16 16:30:01 +08:00
|
|
|
use crate::table::{SsTable, SsTableBuilder, SsTableIterator};
|
2024-01-10 14:25:23 +08:00
|
|
|
|
2024-01-18 17:51:24 +08:00
|
|
|
pub(crate) enum CompactionTask {
|
2024-01-16 16:30:01 +08:00
|
|
|
Leveled(LeveledCompactionTask),
|
|
|
|
|
Tiered(TieredCompactionTask),
|
2024-01-18 17:51:24 +08:00
|
|
|
Simple(SimpleLeveledCompactionTask),
|
2024-01-16 16:30:01 +08:00
|
|
|
}
|
2024-01-10 14:25:23 +08:00
|
|
|
|
|
|
|
|
struct CompactOptions {
|
|
|
|
|
block_size: usize,
|
|
|
|
|
target_sst_size: usize,
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-18 17:51:24 +08:00
|
|
|
pub(crate) enum CompactionController {
|
|
|
|
|
Leveled(LeveledCompactionController),
|
|
|
|
|
Tiered(TieredCompactionController),
|
|
|
|
|
Simple(SimpleLeveledCompactionController),
|
|
|
|
|
NoCompaction,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl CompactionController {
|
|
|
|
|
pub fn flush_to_l0(&self) -> bool {
|
|
|
|
|
if let Self::Leveled(_) | Self::Simple(_) | Self::NoCompaction = self {
|
|
|
|
|
true
|
|
|
|
|
} else {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub enum CompactionOptions {
|
|
|
|
|
/// Leveled compaction with partial compaction + dynamic level support (= RocksDB's Leveled
|
|
|
|
|
/// Compaction)
|
|
|
|
|
Leveled(LeveledCompactionOptions),
|
|
|
|
|
/// Tiered compaction (= RocksDB's universal compaction)
|
|
|
|
|
Tiered(TieredCompactionOptions),
|
|
|
|
|
/// Simple leveled compaction
|
|
|
|
|
Simple(SimpleLeveledCompactionOptions),
|
|
|
|
|
/// In no compaction mode (week 1), always flush to L0
|
|
|
|
|
NoCompaction,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl LsmStorageInner {
|
2024-01-10 14:25:23 +08:00
|
|
|
#[allow(dead_code)]
|
|
|
|
|
fn compact(
|
|
|
|
|
&self,
|
|
|
|
|
tables: Vec<Arc<SsTable>>,
|
|
|
|
|
options: CompactOptions,
|
|
|
|
|
) -> Result<Vec<Arc<SsTable>>> {
|
|
|
|
|
let mut iters = Vec::new();
|
|
|
|
|
iters.reserve(tables.len());
|
|
|
|
|
for table in tables.iter() {
|
2024-01-18 15:15:51 +08:00
|
|
|
iters.push(Box::new(SsTableIterator::create_and_seek_to_first(
|
|
|
|
|
table.clone(),
|
|
|
|
|
)?));
|
2024-01-10 14:25:23 +08:00
|
|
|
}
|
|
|
|
|
let mut iter = MergeIterator::create(iters);
|
|
|
|
|
|
|
|
|
|
let mut builder = None;
|
|
|
|
|
let mut new_sst = vec![];
|
|
|
|
|
|
2024-01-18 17:51:24 +08:00
|
|
|
let compact_to_bottom_level = false;
|
|
|
|
|
|
2024-01-10 14:25:23 +08:00
|
|
|
while iter.is_valid() {
|
|
|
|
|
if builder.is_none() {
|
|
|
|
|
builder = Some(SsTableBuilder::new(options.block_size));
|
|
|
|
|
}
|
|
|
|
|
let builder_inner = builder.as_mut().unwrap();
|
2024-01-18 17:51:24 +08:00
|
|
|
if compact_to_bottom_level {
|
2024-01-10 14:25:23 +08:00
|
|
|
if !iter.value().is_empty() {
|
|
|
|
|
builder_inner.add(iter.key(), iter.value());
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
builder_inner.add(iter.key(), iter.value());
|
|
|
|
|
}
|
|
|
|
|
iter.next()?;
|
|
|
|
|
|
|
|
|
|
if builder_inner.estimated_size() >= options.target_sst_size {
|
|
|
|
|
let sst_id = self.next_sst_id(); // lock dropped here
|
|
|
|
|
let builder = builder.take().unwrap();
|
|
|
|
|
let sst = Arc::new(builder.build(
|
|
|
|
|
sst_id,
|
|
|
|
|
Some(self.block_cache.clone()),
|
|
|
|
|
self.path_of_sst(sst_id),
|
|
|
|
|
)?);
|
|
|
|
|
new_sst.push(sst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if let Some(builder) = builder {
|
|
|
|
|
let sst_id = self.next_sst_id(); // lock dropped here
|
|
|
|
|
let sst = Arc::new(builder.build(
|
|
|
|
|
sst_id,
|
|
|
|
|
Some(self.block_cache.clone()),
|
|
|
|
|
self.path_of_sst(sst_id),
|
|
|
|
|
)?);
|
|
|
|
|
new_sst.push(sst);
|
|
|
|
|
}
|
|
|
|
|
Ok(new_sst)
|
|
|
|
|
}
|
2024-01-18 17:51:24 +08:00
|
|
|
|
|
|
|
|
pub(crate) fn spawn_compaction_thread(
|
|
|
|
|
self: &Arc<Self>,
|
|
|
|
|
rx: std::sync::mpsc::Receiver<()>,
|
|
|
|
|
) -> Result<Option<std::thread::JoinHandle<()>>> {
|
|
|
|
|
Ok(None)
|
|
|
|
|
}
|
2024-01-10 14:25:23 +08:00
|
|
|
}
|