4
4
5
5
use crate :: {
6
6
level_manifest:: level:: Level ,
7
- segment:: { range:: Range , value_block:: CachePolicy } ,
7
+ segment:: { range:: Range , value_block:: CachePolicy , Segment } ,
8
8
InternalValue , UserKey ,
9
9
} ;
10
10
use std:: { ops:: Bound , sync:: Arc } ;
@@ -17,6 +17,7 @@ pub struct LevelReader {
17
17
lo_reader : Option < Range > ,
18
18
hi_reader : Option < Range > ,
19
19
cache_policy : CachePolicy ,
20
+ prefix_hash : Option < ( u64 , u64 ) > ,
20
21
}
21
22
22
23
impl LevelReader {
@@ -25,6 +26,7 @@ impl LevelReader {
25
26
level : Arc < Level > ,
26
27
range : & ( Bound < UserKey > , Bound < UserKey > ) ,
27
28
cache_policy : CachePolicy ,
29
+ prefix_hash : Option < ( u64 , u64 ) > ,
28
30
) -> Self {
29
31
assert ! ( !level. is_empty( ) , "level reader cannot read empty level" ) ;
30
32
@@ -39,10 +41,17 @@ impl LevelReader {
39
41
lo_reader : None ,
40
42
hi_reader : None ,
41
43
cache_policy,
44
+ prefix_hash,
42
45
} ;
43
46
} ;
44
47
45
- Self :: from_indexes ( level, range, ( Some ( lo) , Some ( hi) ) , cache_policy)
48
+ Self :: from_indexes (
49
+ level,
50
+ range,
51
+ ( Some ( lo) , Some ( hi) ) ,
52
+ cache_policy,
53
+ prefix_hash,
54
+ )
46
55
}
47
56
48
57
#[ must_use]
@@ -51,6 +60,7 @@ impl LevelReader {
51
60
range : & ( Bound < UserKey > , Bound < UserKey > ) ,
52
61
( lo, hi) : ( Option < usize > , Option < usize > ) ,
53
62
cache_policy : CachePolicy ,
63
+ prefix_hash : Option < ( u64 , u64 ) > ,
54
64
) -> Self {
55
65
let lo = lo. unwrap_or_default ( ) ;
56
66
let hi = hi. unwrap_or ( level. len ( ) - 1 ) ;
@@ -74,8 +84,14 @@ impl LevelReader {
74
84
lo_reader : Some ( lo_reader) ,
75
85
hi_reader,
76
86
cache_policy,
87
+ prefix_hash,
77
88
}
78
89
}
90
+
91
+ fn may_segment_contain_hash ( & self , segment : & Segment ) -> bool {
92
+ self . prefix_hash
93
+ . map_or ( true , |hash| segment. may_contain_hash ( hash) )
94
+ }
79
95
}
80
96
81
97
impl Iterator for LevelReader {
@@ -90,24 +106,20 @@ impl Iterator for LevelReader {
90
106
91
107
// NOTE: Lo reader is empty, get next one
92
108
self . lo_reader = None ;
93
- self . lo += 1 ;
94
-
95
- if self . lo < self . hi {
96
- self . lo_reader = Some (
97
- self . segments
98
- . get ( self . lo )
99
- . expect ( "should exist" )
100
- . iter ( )
101
- . cache_policy ( self . cache_policy ) ,
102
- ) ;
103
- }
104
- } else if let Some ( hi_reader) = & mut self . hi_reader {
109
+ } else if self . lo == self . hi {
105
110
// NOTE: We reached the hi marker, so consume from it instead
106
111
//
107
112
// If it returns nothing, it is empty, so we are done
108
- return hi_reader. next ( ) ;
113
+ return self . hi_reader . as_mut ( ) . and_then ( |r| r . next ( ) ) ;
109
114
} else {
110
- return None ;
115
+ self . lo += 1 ;
116
+
117
+ if self . lo < self . hi {
118
+ let segment = self . segments . get ( self . lo ) . expect ( "should exist" ) ;
119
+ if self . may_segment_contain_hash ( segment) {
120
+ self . lo_reader = Some ( segment. iter ( ) . cache_policy ( self . cache_policy ) ) ;
121
+ }
122
+ }
111
123
}
112
124
}
113
125
}
@@ -121,26 +133,22 @@ impl DoubleEndedIterator for LevelReader {
121
133
return Some ( item) ;
122
134
}
123
135
124
- // NOTE: Hi reader is empty, get orev one
136
+ // NOTE: Hi reader is empty, get the previous one
125
137
self . hi_reader = None ;
126
- self . hi -= 1 ;
127
-
128
- if self . lo < self . hi {
129
- self . hi_reader = Some (
130
- self . segments
131
- . get ( self . hi )
132
- . expect ( "should exist" )
133
- . iter ( )
134
- . cache_policy ( self . cache_policy ) ,
135
- ) ;
136
- }
137
- } else if let Some ( lo_reader) = & mut self . lo_reader {
138
+ } else if self . lo == self . hi {
138
139
// NOTE: We reached the lo marker, so consume from it instead
139
140
//
140
141
// If it returns nothing, it is empty, so we are done
141
- return lo_reader. next_back ( ) ;
142
+ return self . lo_reader . as_mut ( ) . and_then ( |r| r . next_back ( ) ) ;
142
143
} else {
143
- return None ;
144
+ self . hi -= 1 ;
145
+
146
+ if self . lo < self . hi {
147
+ let segment = self . segments . get ( self . hi ) . expect ( "should exist" ) ;
148
+ if self . may_segment_contain_hash ( segment) {
149
+ self . hi_reader = Some ( segment. iter ( ) . cache_policy ( self . cache_policy ) ) ;
150
+ }
151
+ }
144
152
}
145
153
}
146
154
}
@@ -190,8 +198,12 @@ mod tests {
190
198
191
199
#[ allow( clippy:: unwrap_used) ]
192
200
{
193
- let multi_reader =
194
- LevelReader :: new ( level. clone ( ) , & ( Unbounded , Unbounded ) , CachePolicy :: Read ) ;
201
+ let multi_reader = LevelReader :: new (
202
+ level. clone ( ) ,
203
+ & ( Unbounded , Unbounded ) ,
204
+ CachePolicy :: Read ,
205
+ None ,
206
+ ) ;
195
207
196
208
let mut iter = multi_reader. flatten ( ) ;
197
209
@@ -211,8 +223,12 @@ mod tests {
211
223
212
224
#[ allow( clippy:: unwrap_used) ]
213
225
{
214
- let multi_reader =
215
- LevelReader :: new ( level. clone ( ) , & ( Unbounded , Unbounded ) , CachePolicy :: Read ) ;
226
+ let multi_reader = LevelReader :: new (
227
+ level. clone ( ) ,
228
+ & ( Unbounded , Unbounded ) ,
229
+ CachePolicy :: Read ,
230
+ None ,
231
+ ) ;
216
232
217
233
let mut iter = multi_reader. rev ( ) . flatten ( ) ;
218
234
@@ -232,7 +248,8 @@ mod tests {
232
248
233
249
#[ allow( clippy:: unwrap_used) ]
234
250
{
235
- let multi_reader = LevelReader :: new ( level, & ( Unbounded , Unbounded ) , CachePolicy :: Read ) ;
251
+ let multi_reader =
252
+ LevelReader :: new ( level, & ( Unbounded , Unbounded ) , CachePolicy :: Read , None ) ;
236
253
237
254
let mut iter = multi_reader. flatten ( ) ;
238
255
0 commit comments