turbo_persistence/
sst_filter.rs1use std::collections::hash_map::Entry;
2
3use rustc_hash::{FxHashMap, FxHashSet};
4
5use crate::meta_file::MetaFile;
6
7enum SstState {
8 Active,
9 UnusedObsolete,
10 Obsolete,
11}
12
13pub struct SstFilter(FxHashMap<u32, SstState>);
14
15impl SstFilter {
16 pub fn new() -> Self {
17 Self(FxHashMap::default())
18 }
19
20 pub fn apply_filter(&mut self, meta: &mut MetaFile) {
22 for seq in meta.obsolete_entries() {
24 if let Some(state) = self.0.get_mut(seq)
25 && matches!(state, SstState::UnusedObsolete)
26 {
27 *state = SstState::Obsolete;
29 }
30 }
31 meta.retain_entries(|seq| match self.0.entry(seq) {
32 Entry::Occupied(mut e) => {
33 let state = e.get_mut();
34 if matches!(state, SstState::UnusedObsolete) {
35 *state = SstState::Obsolete;
37 }
38 false
39 }
40 Entry::Vacant(e) => {
41 e.insert(SstState::Active);
42 true
43 }
44 });
45 for seq in meta.obsolete_sst_files() {
46 self.0.entry(*seq).or_insert(SstState::UnusedObsolete);
47 }
48 }
49
50 pub fn apply_filter_collect(&mut self, meta: &MetaFile) -> FxHashSet<u32> {
55 let mut to_remove = FxHashSet::default();
56 for seq in meta.obsolete_entries() {
58 if let Some(state) = self.0.get_mut(seq)
59 && matches!(state, SstState::UnusedObsolete)
60 {
61 *state = SstState::Obsolete;
63 }
64 }
65 for entry in meta.entries() {
66 let seq = entry.sequence_number();
67 match self.0.entry(seq) {
68 Entry::Occupied(mut e) => {
69 let state = e.get_mut();
70 if matches!(state, SstState::UnusedObsolete) {
71 *state = SstState::Obsolete;
72 }
73 to_remove.insert(seq);
74 }
75 Entry::Vacant(e) => {
76 e.insert(SstState::Active);
77 }
78 }
79 }
80 for seq in meta.obsolete_sst_files() {
81 self.0.entry(*seq).or_insert(SstState::UnusedObsolete);
82 }
83 to_remove
84 }
85
86 pub fn apply_and_get_remove(&mut self, meta: &MetaFile) -> bool {
90 let mut used = false;
91 for seq in meta.obsolete_sst_files() {
92 if let Entry::Occupied(e) = self.0.entry(*seq) {
93 if matches!(e.get(), SstState::Obsolete) {
94 used = true;
96 }
97 e.remove();
100 }
101 }
102
103 !used && !meta.has_active_entries()
104 }
105}
106
107impl Default for SstFilter {
108 fn default() -> Self {
109 Self::new()
110 }
111}