@@ -116,108 +116,95 @@ impl Segment {
116116 }
117117 }
118118
119+ // Get the block handle, if it doesn't exist, the key is definitely not found
120+ let Some ( block_handle) = self . block_index . get_latest ( key. as_ref ( ) ) ? else {
121+ return Ok ( None ) ;
122+ } ;
123+
124+ // The block should definitely exist, we just got the block handle before
125+ let Some ( block) = load_and_cache_by_block_handle (
126+ & self . descriptor_table ,
127+ & self . block_cache ,
128+ & self . metadata . id ,
129+ & block_handle,
130+ ) ?
131+ else {
132+ return Ok ( None ) ;
133+ } ;
134+
135+ let mut maybe_our_items_iter = block
136+ . items
137+ . iter ( )
138+ // TODO: maybe binary search can be used, but it needs to find the max seqno
139+ . filter ( |item| item. key == key. as_ref ( ) . into ( ) ) ;
140+
119141 match seqno {
120142 None => {
121143 // NOTE: Fastpath for non-seqno reads (which are most common)
122144 // This avoids setting up a rather expensive block iterator
123145 // (see explanation for that below)
124146 // This only really works because sequence numbers are sorted
125147 // in descending order
148+ //
149+ // If it doesn't exist, we avoid loading the next block
150+ // because the block handle was retrieved using the item key, so if
151+ // the item exists, it HAS to be in the first block
126152
127- if let Some ( block_handle) = self . block_index . get_latest ( key. as_ref ( ) ) ? {
128- let block = load_and_cache_by_block_handle (
129- & self . descriptor_table ,
130- & self . block_cache ,
131- & self . metadata . id ,
132- & block_handle,
133- ) ?;
134-
135- let item = block. map_or_else (
136- || Ok ( None ) ,
137- |block| {
138- // TODO: maybe binary search can be used, but it needs to find the max seqno
139- Ok ( block
140- . items
141- . iter ( )
142- . find ( |item| item. key == key. as_ref ( ) . into ( ) )
143- . cloned ( ) )
144- } ,
145- ) ;
146-
147- item
148- } else {
149- Ok ( None )
150- }
153+ Ok ( maybe_our_items_iter. next ( ) . cloned ( ) )
151154 }
152155 Some ( seqno) => {
153- // NOTE: if block does not contain entry, fallback to prefix as seen below
154- if let Some ( block_handle) = self . block_index . get_latest ( key. as_ref ( ) ) ? {
155- let block = load_and_cache_by_block_handle (
156- & self . descriptor_table ,
157- & self . block_cache ,
158- & self . metadata . id ,
159- & block_handle,
160- ) ?;
161-
162- if let Some ( block) = block {
163- for item in block
164- . items
165- . iter ( )
166- // TODO: maybe binary search can be used, but it needs to find the max seqno
167- . filter ( |item| item. key == key. as_ref ( ) . into ( ) )
168- {
169- if item. seqno < seqno {
170- return Ok ( Some ( item. clone ( ) ) ) ;
171- }
172- }
156+ for item in maybe_our_items_iter {
157+ if item. seqno < seqno {
158+ return Ok ( Some ( item. clone ( ) ) ) ;
173159 }
160+ }
174161
175- // NOTE: For finding a specific seqno,
176- // we need to use a prefixed reader
177- // because nothing really prevents the version
178- // we are searching for to be in the next block
179- // after the one our key starts in
180- //
181- // Example (key:seqno), searching for a:2:
182- //
183- // [..., a:5, a:4] [a:3, a:2, b: 4, b:3]
184- // ^ ^
185- // Block A Block B
186- //
187- // Based on get_lower_bound_block, "a" is in Block A
188- // However, we are searching for A with seqno 2, which
189- // unfortunately is in the next block
190-
191- let Some ( next_block_handle) = self
192- . block_index
193- . get_next_block_key ( & block_handle. start_key ) ?
194- else {
162+ // NOTE: If we got here, the item was not in the block :(
163+
164+ // NOTE: For finding a specific seqno,
165+ // we need to use a prefixed reader
166+ // because nothing really prevents the version
167+ // we are searching for to be in the next block
168+ // after the one our key starts in
169+ //
170+ // Example (key:seqno), searching for a:2:
171+ //
172+ // [..., a:5, a:4] [a:3, a:2, b: 4, b:3]
173+ // ^ ^
174+ // Block A Block B
175+ //
176+ // Based on get_lower_bound_block, "a" is in Block A
177+ // However, we are searching for A with seqno 2, which
178+ // unfortunately is in the next block
179+
180+ // Load next block and setup block iterator
181+ let Some ( next_block_handle) = self
182+ . block_index
183+ . get_next_block_key ( & block_handle. start_key ) ?
184+ else {
185+ return Ok ( None ) ;
186+ } ;
187+
188+ let iter = Reader :: new (
189+ Arc :: clone ( & self . descriptor_table ) ,
190+ self . metadata . id . clone ( ) ,
191+ Some ( Arc :: clone ( & self . block_cache ) ) ,
192+ Arc :: clone ( & self . block_index ) ,
193+ Some ( & next_block_handle. start_key ) ,
194+ None ,
195+ ) ;
196+
197+ for item in iter {
198+ let item = item?;
199+
200+ // Just stop iterating once we go past our desired key
201+ if & * item. key != key {
195202 return Ok ( None ) ;
196- } ;
197-
198- let iter = Reader :: new (
199- Arc :: clone ( & self . descriptor_table ) ,
200- self . metadata . id . clone ( ) ,
201- Some ( Arc :: clone ( & self . block_cache ) ) ,
202- Arc :: clone ( & self . block_index ) ,
203- Some ( & next_block_handle. start_key ) ,
204- None ,
205- ) ;
206-
207- for item in iter {
208- let item = item?;
209-
210- // Just stop iterating once we go past our desired key
211- if & * item. key != key {
212- return Ok ( None ) ;
213- }
214-
215- if item. seqno < seqno {
216- return Ok ( Some ( item) ) ;
217- }
218203 }
219- } else {
220- return Ok ( None ) ;
204+
205+ if item. seqno < seqno {
206+ return Ok ( Some ( item) ) ;
207+ }
221208 }
222209
223210 Ok ( None )
0 commit comments