Skip to content

Commit 41781cc

Browse files
committed
address more pr feedback
1 parent 5e53adb commit 41781cc

File tree

13 files changed

+630
-396
lines changed

13 files changed

+630
-396
lines changed

src/compaction/pulldown.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// This source code is licensed under both the Apache 2.0 and MIT License
33
// (found in the LICENSE-* files in the repository)
44

5-
use super::{Choice, CompactionStrategy, Input};
6-
use crate::{level_manifest::LevelManifest, segment::Segment, Config, HashSet};
5+
use super::{Choice, CompactionStrategy};
6+
use crate::{config::Config, level_manifest::LevelManifest};
77

88
/// Pulls down and merges a level into the destination level.
99
///

src/compaction/tiered.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// This source code is licensed under both the Apache 2.0 and MIT License
33
// (found in the LICENSE-* files in the repository)
44

5-
use super::{Choice, CompactionStrategy, Input as CompactionInput};
6-
use crate::{level_manifest::LevelManifest, segment::Segment, Config, HashSet};
5+
use super::{Choice, CompactionStrategy};
6+
use crate::{config::Config, level_manifest::LevelManifest};
77

88
fn desired_level_size_in_bytes(level_idx: u8, ratio: u8, base_size: u32) -> usize {
99
(ratio as usize).pow(u32::from(level_idx + 1)) * (base_size as usize)

src/compaction/worker.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{
1212
level_manifest::LevelManifest,
1313
merge::Merger,
1414
run_scanner::RunScanner,
15-
segment::{multi_writer::MultiWriter, Segment},
15+
segment::{multi_writer::MultiWriter, RecoverParams, Segment},
1616
stop_signal::StopSignal,
1717
tree::inner::TreeId,
1818
Config, InternalValue, SegmentId, SeqNo,
@@ -359,17 +359,17 @@ fn merge_segments(
359359
let created_segments = writer_results
360360
.into_iter()
361361
.map(|segment_id| -> crate::Result<Segment> {
362-
Segment::recover(
363-
segments_base_folder.join(segment_id.to_string()),
364-
opts.tree_id,
365-
opts.config.cache.clone(),
366-
opts.config.descriptor_table.clone(),
367-
opts.config.prefix_extractor.clone(),
368-
payload.dest_level <= 1, // TODO: look at configuration
369-
payload.dest_level <= 2, // TODO: look at configuration
362+
Segment::recover(RecoverParams {
363+
file_path: segments_base_folder.join(segment_id.to_string()),
364+
tree_id: opts.tree_id,
365+
cache: opts.config.cache.clone(),
366+
descriptor_table: opts.config.descriptor_table.clone(),
367+
prefix_extractor: opts.config.prefix_extractor.clone(),
368+
pin_filter: payload.dest_level <= 1, // TODO: look at configuration
369+
pin_index: payload.dest_level <= 2, // TODO: look at configuration
370370
#[cfg(feature = "metrics")]
371-
opts.metrics.clone(),
372-
)
371+
metrics: opts.metrics.clone(),
372+
})
373373

374374
/* let segment_id = trailer.metadata.id;
375375
let segment_file_path = segments_base_folder.join(segment_id.to_string());

src/prefix.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,27 @@ use std::sync::Arc;
2929
/// }
3030
/// ```
3131
///
32-
/// ## Segmented prefixes (e.g., `account_id#user_id)`:
32+
/// ## Domain-based prefixes (e.g., `example.com@user`):
3333
/// ```
3434
/// use lsm_tree::prefix::PrefixExtractor;
3535
///
36-
/// struct SegmentedPrefixExtractor;
36+
/// struct DomainPrefixExtractor;
3737
///
38-
/// impl PrefixExtractor for SegmentedPrefixExtractor {
38+
/// impl PrefixExtractor for DomainPrefixExtractor {
3939
/// fn extract<'a>(&self, key: &'a [u8]) -> Box<dyn Iterator<Item = &'a [u8]> + 'a> {
40-
/// let mut prefixes = vec![];
41-
/// let mut end = 0;
42-
/// for (i, &byte) in key.iter().enumerate() {
43-
/// if byte == b'#' {
44-
/// prefixes.push(&key[0..i]);
45-
/// end = i;
46-
/// }
47-
/// }
48-
/// if end < key.len() {
49-
/// prefixes.push(key);
40+
/// // Extract domain prefix before '@' separator
41+
/// // This allows efficient scans over all users in a domain
42+
/// // e.g., "example.com@alice" -> "example.com"
43+
/// if let Some(pos) = key.iter().position(|&b| b == b'@') {
44+
/// Box::new(std::iter::once(&key[0..pos]))
45+
/// } else {
46+
/// // If no separator, use the full key
47+
/// Box::new(std::iter::once(key))
5048
/// }
51-
/// Box::new(prefixes.into_iter())
5249
/// }
5350
///
5451
/// fn name(&self) -> &str {
55-
/// "segmented_prefix"
52+
/// "domain_prefix"
5653
/// }
5754
/// }
5855
/// ```
@@ -66,6 +63,12 @@ pub trait PrefixExtractor: Send + Sync {
6663

6764
/// Returns a unique name for this prefix extractor.
6865
fn name(&self) -> &str;
66+
67+
/// Returns the first prefix for a key, if any.
68+
/// This is an optimization to avoid boxing for the common case.
69+
fn extract_first<'a>(&self, key: &'a [u8]) -> Option<&'a [u8]> {
70+
self.extract(key).next()
71+
}
6972
}
7073

7174
/// A prefix extractor that returns the full key.
@@ -81,6 +84,10 @@ impl PrefixExtractor for FullKeyExtractor {
8184
fn name(&self) -> &'static str {
8285
"full_key"
8386
}
87+
88+
fn extract_first<'a>(&self, key: &'a [u8]) -> Option<&'a [u8]> {
89+
Some(key)
90+
}
8491
}
8592

8693
/// A prefix extractor that returns a fixed-length prefix.
@@ -112,6 +119,14 @@ impl PrefixExtractor for FixedPrefixExtractor {
112119
fn name(&self) -> &'static str {
113120
"fixed_prefix"
114121
}
122+
123+
fn extract_first<'a>(&self, key: &'a [u8]) -> Option<&'a [u8]> {
124+
if key.len() <= self.length {
125+
Some(key)
126+
} else {
127+
key.get(0..self.length)
128+
}
129+
}
115130
}
116131

117132
/// A prefix extractor that requires keys to be at least a certain length.

0 commit comments

Comments
 (0)