@@ -29,30 +29,27 @@ use std::sync::Arc;
29
29
/// }
30
30
/// ```
31
31
///
32
- /// ## Segmented prefixes (e.g., `account_id#user_id)` :
32
+ /// ## Domain-based prefixes (e.g., `example.com@user`) :
33
33
/// ```
34
34
/// use lsm_tree::prefix::PrefixExtractor;
35
35
///
36
- /// struct SegmentedPrefixExtractor ;
36
+ /// struct DomainPrefixExtractor ;
37
37
///
38
- /// impl PrefixExtractor for SegmentedPrefixExtractor {
38
+ /// impl PrefixExtractor for DomainPrefixExtractor {
39
39
/// 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))
50
48
/// }
51
- /// Box::new(prefixes.into_iter())
52
49
/// }
53
50
///
54
51
/// fn name(&self) -> &str {
55
- /// "segmented_prefix "
52
+ /// "domain_prefix "
56
53
/// }
57
54
/// }
58
55
/// ```
@@ -66,6 +63,12 @@ pub trait PrefixExtractor: Send + Sync {
66
63
67
64
/// Returns a unique name for this prefix extractor.
68
65
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
+ }
69
72
}
70
73
71
74
/// A prefix extractor that returns the full key.
@@ -81,6 +84,10 @@ impl PrefixExtractor for FullKeyExtractor {
81
84
fn name ( & self ) -> & ' static str {
82
85
"full_key"
83
86
}
87
+
88
+ fn extract_first < ' a > ( & self , key : & ' a [ u8 ] ) -> Option < & ' a [ u8 ] > {
89
+ Some ( key)
90
+ }
84
91
}
85
92
86
93
/// A prefix extractor that returns a fixed-length prefix.
@@ -112,6 +119,14 @@ impl PrefixExtractor for FixedPrefixExtractor {
112
119
fn name ( & self ) -> & ' static str {
113
120
"fixed_prefix"
114
121
}
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
+ }
115
130
}
116
131
117
132
/// A prefix extractor that requires keys to be at least a certain length.
0 commit comments