Skip to content

Commit a711de5

Browse files
committed
adjust leveled compaction
1 parent 9ae99a1 commit a711de5

File tree

3 files changed

+54
-11
lines changed

3 files changed

+54
-11
lines changed

src/compaction/leveled/mod.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,36 @@ impl CompactionStrategy for Strategy {
277277
fn choose(&self, version: &Version, _: &Config, state: &CompactionState) -> Choice {
278278
assert!(version.level_count() == 7, "should have exactly 7 levels");
279279

280+
// Trivial move into Lmax
281+
'trivial_lmax: {
282+
let l0 = version.level(0).expect("first level should exist");
283+
284+
if !l0.is_empty() && l0.is_disjoint() {
285+
let lmax_index = version.level_count() - 1;
286+
287+
if (1..lmax_index)
288+
.any(|idx| !version.level(idx).expect("level should exist").is_empty())
289+
{
290+
// There are intermediary levels with data, cannot trivially move to Lmax
291+
break 'trivial_lmax;
292+
}
293+
294+
let lmax = version.level(lmax_index).expect("last level should exist");
295+
296+
if !lmax
297+
.aggregate_key_range()
298+
.overlaps_with_key_range(&l0.aggregate_key_range())
299+
{
300+
return Choice::Move(CompactionInput {
301+
table_ids: l0.list_ids(),
302+
dest_level: lmax_index as u8,
303+
canonical_level: 1,
304+
target_size: self.target_size,
305+
});
306+
}
307+
}
308+
}
309+
280310
// Find the level that corresponds to L1
281311
#[expect(clippy::map_unwrap_or)]
282312
let first_non_empty_level = version

src/compaction/leveled/test.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::Strategy;
1+
use super::*;
22
use crate::{AbstractTree, Config, SequenceNumberCounter};
33
use std::sync::Arc;
44
use test_log::test;
@@ -137,6 +137,7 @@ fn leveled_l0_reached_limit_disjoint_l1() -> crate::Result<()> {
137137
}
138138

139139
#[test]
140+
#[expect(clippy::unwrap_used)]
140141
fn leveled_sequential_inserts() -> crate::Result<()> {
141142
let dir = tempfile::tempdir()?;
142143
let tree = Config::new(
@@ -146,18 +147,30 @@ fn leveled_sequential_inserts() -> crate::Result<()> {
146147
)
147148
.open()?;
148149

149-
for (table_count, k) in ('a'..='z').enumerate() {
150-
let table_count = table_count + 1;
150+
let strategy = Arc::new(Strategy {
151+
target_size: 1,
152+
..Default::default()
153+
});
151154

152-
// NOTE: Tables need to overlap
153-
tree.insert(k.to_string(), "", 0);
155+
let mut table_count = 0;
156+
157+
for k in 0u64..100 {
158+
table_count += 1;
159+
160+
tree.insert(k.to_be_bytes(), "", 0);
154161
tree.flush_active_memtable(0)?;
155162

156163
assert_eq!(table_count, tree.table_count());
157-
158-
let strategy = Arc::new(Strategy::default());
159-
tree.compact(strategy, 0)?;
164+
tree.compact(strategy.clone(), 0)?;
160165
assert_eq!(table_count, tree.table_count());
166+
167+
for idx in 1..=5 {
168+
assert_eq!(
169+
0,
170+
tree.current_version().level(idx).unwrap().len(),
171+
"no tables should be in intermediary level (L{idx})",
172+
);
173+
}
161174
}
162175

163176
Ok(())

tests/leveled_trivial_move.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ fn leveled_trivial_move_into_l1() -> lsm_tree::Result<()> {
1818
tree.insert("a", "a", 0);
1919
tree.flush_active_memtable(0)?;
2020
tree.compact(compaction.clone(), 0)?;
21-
assert_eq!(1, tree.level_table_count(0).unwrap_or_default());
21+
assert_eq!(1, tree.level_table_count(6).unwrap_or_default());
2222

2323
tree.insert("b", "b", 0);
2424
tree.flush_active_memtable(0)?;
2525
tree.compact(compaction.clone(), 0)?;
26-
assert_eq!(2, tree.level_table_count(0).unwrap_or_default());
26+
assert_eq!(2, tree.level_table_count(6).unwrap_or_default());
2727

2828
tree.insert("c", "c", 0);
2929
tree.flush_active_memtable(0)?;
3030
tree.compact(compaction.clone(), 0)?;
31-
assert_eq!(3, tree.level_table_count(0).unwrap_or_default());
31+
assert_eq!(3, tree.level_table_count(6).unwrap_or_default());
3232

3333
tree.insert("d", "d", 0);
3434
tree.flush_active_memtable(0)?;

0 commit comments

Comments
 (0)