@@ -192,10 +192,14 @@ impl ReadableKeyValueStore for IndexedDbStore {
192192 key_interval : KeyInterval ,
193193 ) -> Result < ( Vec < Vec < u8 > > , bool ) > {
194194 let range = interval_to_range ( & self . start_key , & key_interval) ;
195- let keys = self
196- . with_object_store ( move |o| {
197- o. get_all_keys_in ( range, key_interval. limit . map ( |limit| limit as u32 ) )
198- } )
195+ // Ask for one extra key past the user limit so we can decide
196+ // `is_finished` precisely without an extra round-trip.
197+ let user_limit = key_interval. limit ;
198+ let fetch_limit = user_limit. map ( |limit| {
199+ u32:: try_from ( limit. saturating_add ( 1 ) . min ( u32:: MAX as usize ) ) . unwrap_or ( u32:: MAX )
200+ } ) ;
201+ let mut keys = self
202+ . with_object_store ( move |o| o. get_all_keys_in ( range, fetch_limit) )
199203 . await ??
200204 . into_iter ( )
201205 . map ( |key| {
@@ -204,7 +208,17 @@ impl ReadableKeyValueStore for IndexedDbStore {
204208 . to_vec ( )
205209 } )
206210 . collect :: < Vec < _ > > ( ) ;
207- let is_finished = key_interval. limit . is_none_or ( |limit| keys. len ( ) < limit) ;
211+ let is_finished = match user_limit {
212+ Some ( limit) => {
213+ if keys. len ( ) > limit {
214+ keys. truncate ( limit) ;
215+ false
216+ } else {
217+ true
218+ }
219+ }
220+ None => true ,
221+ } ;
208222 Ok ( ( keys, is_finished) )
209223 }
210224
@@ -214,7 +228,12 @@ impl ReadableKeyValueStore for IndexedDbStore {
214228 ) -> Result < ( Vec < ( Vec < u8 > , Vec < u8 > ) > , bool ) > {
215229 let range = interval_to_range ( & self . start_key , & key_interval) ;
216230 let prefix_len = self . start_key . len ( ) as u32 ;
217- let key_values = self
231+ let user_limit = key_interval. limit ;
232+ // Walk one cursor step past the user limit so we know whether the
233+ // database has more matches — the cursor advance is the only extra
234+ // cost.
235+ let fetch_target = user_limit. map ( |limit| limit. saturating_add ( 1 ) ) ;
236+ let mut key_values = self
218237 . with_object_store ( move |object_store| async move {
219238 let mut key_values = vec ! [ ] ;
220239 let mut cursor = object_store. cursor ( ) . range ( range) ?. open ( ) . await ?;
@@ -230,10 +249,7 @@ impl ReadableKeyValueStore for IndexedDbStore {
230249 )
231250 . to_vec ( ) ,
232251 ) ) ;
233- if key_interval
234- . limit
235- . is_some_and ( |limit| key_values. len ( ) >= limit)
236- {
252+ if fetch_target. is_some_and ( |target| key_values. len ( ) >= target) {
237253 break ;
238254 }
239255 cursor. advance ( 1 ) . await ?;
@@ -242,9 +258,17 @@ impl ReadableKeyValueStore for IndexedDbStore {
242258 Ok :: < _ , IndexedDbStoreError > ( key_values)
243259 } )
244260 . await ??;
245- let is_finished = key_interval
246- . limit
247- . is_none_or ( |limit| key_values. len ( ) < limit) ;
261+ let is_finished = match user_limit {
262+ Some ( limit) => {
263+ if key_values. len ( ) > limit {
264+ key_values. truncate ( limit) ;
265+ false
266+ } else {
267+ true
268+ }
269+ }
270+ None => true ,
271+ } ;
248272 Ok ( ( key_values, is_finished) )
249273 }
250274}
0 commit comments