Skip to main content

risingwave_meta/hummock/compaction/selector/
tombstone_compaction_selector.rs

1// Copyright 2023 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::collections::HashMap;
16
17use risingwave_hummock_sdk::{CompactionGroupId, HummockCompactionTaskId};
18use risingwave_pb::hummock::compact_task;
19
20use super::{CompactionSelector, DynamicLevelSelectorCore};
21use crate::hummock::compaction::picker::{
22    TombstoneReclaimCompactionPicker, TombstoneReclaimPickerState,
23};
24use crate::hummock::compaction::selector::CompactionSelectorContext;
25use crate::hummock::compaction::{CompactionTask, create_compaction_task, create_overlap_strategy};
26
27#[derive(Default)]
28pub struct TombstoneCompactionSelector {
29    state: HashMap<CompactionGroupId, TombstoneReclaimPickerState>,
30}
31
32impl CompactionSelector for TombstoneCompactionSelector {
33    fn pick_compaction(
34        &mut self,
35        task_id: HummockCompactionTaskId,
36        context: CompactionSelectorContext<'_>,
37    ) -> Option<CompactionTask> {
38        let CompactionSelectorContext {
39            group,
40            levels,
41            level_handlers,
42            developer_config,
43            in_progress_compactions,
44            ..
45        } = context;
46        if group.compaction_config.tombstone_reclaim_ratio == 0 {
47            // it might cause full-compaction when tombstone_reclaim_ratio == 0
48            return None;
49        }
50
51        let dynamic_level_core =
52            DynamicLevelSelectorCore::new(group.compaction_config.clone(), developer_config);
53        let ctx = dynamic_level_core.calculate_level_base_size(levels);
54        let picker = TombstoneReclaimCompactionPicker::new(
55            create_overlap_strategy(group.compaction_config.compaction_mode()),
56            group.compaction_config.tombstone_reclaim_ratio as u64,
57            group.compaction_config.tombstone_reclaim_ratio as u64 / 2,
58        );
59        let state = self.state.entry(group.group_id).or_default();
60        let compaction_input = picker.pick_compaction(levels, level_handlers, state)?;
61        if !compaction_input.skip_target_range_conflict_check
62            && in_progress_compactions.has_conflict_with_input(&compaction_input)
63        {
64            return None;
65        }
66        compaction_input.add_pending_task(task_id, level_handlers);
67
68        Some(create_compaction_task(
69            group.compaction_config.as_ref(),
70            compaction_input,
71            ctx.base_level,
72            self.task_type(),
73        ))
74    }
75
76    fn name(&self) -> &'static str {
77        "TombstoneCompaction"
78    }
79
80    fn task_type(&self) -> compact_task::TaskType {
81        compact_task::TaskType::Tombstone
82    }
83}