Skip to content

Commit

Permalink
Simplify Indexed DB batching code by starting from an empty-string key
Browse files Browse the repository at this point in the history
  • Loading branch information
andybalaam committed Jan 17, 2024
1 parent 7823dd8 commit ff3dd05
Showing 1 changed file with 10 additions and 24 deletions.
34 changes: 10 additions & 24 deletions crates/matrix-sdk-indexeddb/src/crypto_store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1205,44 +1205,30 @@ async fn fetch_from_object_store_batched<R, F>(
where
F: Fn(JsValue) -> Result<R>,
{
enum NextBatch {
First, // In the first batch we don't start from a key
Later(JsValue), // In later batches we have a starting key
}

let mut result = Vec::new();
let mut next_batch = NextBatch::First;
let mut batch_n = 0;

// The empty string is before all keys in Indexed DB - first batch starts there.
let mut latest_key: JsValue = "".into();

loop {
debug!("Fetching Indexed DB records starting from {}", batch_n * batch_size);

// See https://github.com/Alorel/rust-indexed-db/issues/31 - we
// would like to use `get_all_with_key_and_limit` if it ever exists
// but for now we use a cursor and manually limit batch size.

// Get hold of a cursor for this batch
let cursor = match &next_batch {
NextBatch::First => object_store.open_cursor(),

NextBatch::Later(latest_key) => {
// We want a cursor starting after the last key we processed
let after_latest_key = IdbKeyRange::lower_bound_with_open(latest_key, true);

// This key should always be valid since it was returned by `cursor.key()`.
// (Note: the key doesn't have to exist to be valid, so even if
// somehow the entry was deleted, we should not panic here.)
let after_latest_key = after_latest_key.expect("Key was not valid!");

object_store.open_cursor_with_range(&after_latest_key)
}
}?
.await?;
// Get hold of a cursor for this batch. (This should not panic in expect()
// because we always use "", or the result of cursor.key(), both of
// which are valid keys.)
let after_latest_key =
IdbKeyRange::lower_bound_with_open(&latest_key, true).expect("Key was not valid!");
let cursor = object_store.open_cursor_with_range(&after_latest_key)?.await?;

// Fetch batch_size records into result
let next_key = fetch_batch(cursor, batch_size, &f, &mut result).await?;
if let Some(next_key) = next_key {
next_batch = NextBatch::Later(next_key);
latest_key = next_key;
} else {
break;
}
Expand Down

0 comments on commit ff3dd05

Please sign in to comment.