add simple leveled compaction

Signed-off-by: Alex Chi Z <iskyzh@gmail.com>
This commit is contained in:
Alex Chi Z
2024-01-17 15:42:33 +08:00
parent f93a8a1bd8
commit 70b1da4553
5 changed files with 238 additions and 18 deletions

View File

@@ -1,7 +1,8 @@
use crate::lsm_storage::LsmStorageInner;
pub struct LeveledCompactionTask {
upper_level: usize,
// if upper_level is `None`, then it is L0 compaction
upper_level: Option<usize>,
upper_level_sst_ids: Vec<usize>,
lower_level: usize,
lower_level_sst_ids: Vec<usize>,

View File

@@ -0,0 +1,100 @@
use std::collections::HashMap;
use crate::lsm_storage::LsmStorageInner;
pub struct SimpleLeveledCompactionOptions {
pub size_ratio_percent: usize,
pub level0_file_num_compaction_trigger: usize,
pub max_levels: usize,
}
pub struct SimpleLeveledCompactionTask {
// if upper_level is `None`, then it is L0 compaction
pub upper_level: Option<usize>,
pub upper_level_sst_ids: Vec<usize>,
pub lower_level: usize,
pub lower_level_sst_ids: Vec<usize>,
}
pub struct SimpleLeveledCompactionController {
options: SimpleLeveledCompactionOptions,
}
impl SimpleLeveledCompactionController {
pub fn new(options: SimpleLeveledCompactionOptions) -> Self {
Self { options }
}
pub fn generate_compaction_task(
&mut self,
snapshot: &LsmStorageInner,
) -> Option<SimpleLeveledCompactionTask> {
let mut level_sizes = Vec::new();
level_sizes.push(snapshot.l0_sstables.len());
for (_, files) in &snapshot.levels {
level_sizes.push(files.len());
}
for i in 0..self.options.max_levels {
if i == 0
&& snapshot.l0_sstables.len() < self.options.level0_file_num_compaction_trigger
{
continue;
}
let lower_level = i + 1;
let size_ratio = level_sizes[lower_level] as f64 / level_sizes[i] as f64;
if size_ratio < self.options.size_ratio_percent as f64 / 100.0 {
println!(
"compaction triggered at level {} and {} with size ratio {}",
i, lower_level, size_ratio
);
return Some(SimpleLeveledCompactionTask {
upper_level: if i == 0 { None } else { Some(i) },
upper_level_sst_ids: if i == 0 {
snapshot.l0_sstables.clone()
} else {
snapshot.levels[i - 1].1.clone()
},
lower_level,
lower_level_sst_ids: snapshot.levels[lower_level - 1].1.clone(),
});
}
}
None
}
pub fn apply_compaction_result(
&self,
snapshot: &LsmStorageInner,
task: &SimpleLeveledCompactionTask,
output: &[usize],
) -> (LsmStorageInner, Vec<usize>) {
let mut snapshot = snapshot.clone();
let mut files_to_remove = Vec::new();
if let Some(upper_level) = task.upper_level {
assert_eq!(
task.upper_level_sst_ids,
snapshot.levels[upper_level - 1].1,
"sst mismatched"
);
files_to_remove.extend(&snapshot.levels[upper_level - 1].1);
snapshot.levels[upper_level - 1].1.clear();
} else {
assert_eq!(
task.upper_level_sst_ids, snapshot.l0_sstables,
"sst mismatched"
);
files_to_remove.extend(&snapshot.l0_sstables);
snapshot.l0_sstables.clear();
}
assert_eq!(
task.lower_level_sst_ids,
snapshot.levels[task.lower_level - 1].1,
"sst mismatched"
);
files_to_remove.extend(&snapshot.levels[task.lower_level - 1].1);
snapshot.levels[task.lower_level - 1].1 = output.to_vec();
(snapshot, files_to_remove)
}
}