use super::{Choice, CompactionStrategy, Input as CompactionInput};
use crate::{
HashSet, compaction::state::CompactionState, config::Config, heal_hints::HealHints,
version::Version,
};
use alloc::sync::Arc;
pub const NAME: &str = "EccHealCompaction";
pub struct Strategy {
hints: Arc<HealHints>,
target_size: u64,
}
impl Strategy {
#[must_use]
pub fn new(hints: Arc<HealHints>, target_size: u64) -> Self {
Self { hints, target_size }
}
}
impl CompactionStrategy for Strategy {
fn get_name(&self) -> &'static str {
NAME
}
fn choose(&self, version: &Version, _cfg: &Config, state: &CompactionState) -> Choice {
while let Some(global_id) = self.hints.pop() {
let table_id = global_id.table_id();
let Some(level_idx) = version
.iter_levels()
.position(|level| level.list_ids().contains(&table_id))
else {
continue;
};
if state.hidden_set().is_hidden(table_id) {
self.hints.record(global_id);
return Choice::DoNothing;
}
#[expect(
clippy::cast_possible_truncation,
reason = "level index is bounded by level_count, which is a u8"
)]
let level = level_idx as u8;
return Choice::Merge(CompactionInput {
table_ids: core::iter::once(table_id).collect::<HashSet<_>>(),
dest_level: level,
canonical_level: level,
target_size: self.target_size,
});
}
Choice::DoNothing
}
}
#[cfg(test)]
mod strategy_tests;
#[cfg(all(test, feature = "page_ecc"))]
mod tests;