Skip to content

Commit 392a1ef

Browse files
mgoldenbergHywan
authored andcommitted
feat(indexeddb): add IndexedDB-backed impl for EventCacheStore::load_previous_chunk
Signed-off-by: Michael Goldenberg <m@mgoldenberg.net>
1 parent c5f2460 commit 392a1ef

File tree

2 files changed

+80
-4
lines changed

2 files changed

+80
-4
lines changed

crates/matrix-sdk-indexeddb/src/event_cache_store/integration_tests.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,59 @@ pub async fn test_load_last_chunk(store: IndexeddbEventCacheStore) {
502502
assert_eq!(chunk_identifier_generator.current(), 42);
503503
}
504504

505+
pub async fn test_load_previous_chunk(store: IndexeddbEventCacheStore) {
506+
let room_id = &DEFAULT_TEST_ROOM_ID;
507+
let linked_chunk_id = LinkedChunkId::Room(room_id);
508+
let event = |msg: &str| make_test_event(room_id, msg);
509+
510+
// Case #1: no chunk at all, equivalent to having an nonexistent
511+
// `before_chunk_identifier`.
512+
let previous_chunk =
513+
store.load_previous_chunk(linked_chunk_id, ChunkIdentifier::new(153)).await.unwrap();
514+
assert!(previous_chunk.is_none());
515+
516+
// Case #2: there is one chunk only: we request the previous on this
517+
// one, it doesn't exist.
518+
let updates =
519+
vec![Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None }];
520+
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
521+
522+
let previous_chunk =
523+
store.load_previous_chunk(linked_chunk_id, ChunkIdentifier::new(42)).await.unwrap();
524+
assert!(previous_chunk.is_none());
525+
526+
// Case #3: there are two chunks.
527+
let updates = vec![
528+
// new chunk before the one that exists.
529+
Update::NewItemsChunk {
530+
previous: None,
531+
new: ChunkIdentifier::new(7),
532+
next: Some(ChunkIdentifier::new(42)),
533+
},
534+
Update::PushItems {
535+
at: Position::new(ChunkIdentifier::new(7), 0),
536+
items: vec![event("brigand du jorat"), event("morbier")],
537+
},
538+
];
539+
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
540+
541+
let previous_chunk =
542+
store.load_previous_chunk(linked_chunk_id, ChunkIdentifier::new(42)).await.unwrap();
543+
544+
assert_matches!(previous_chunk, Some(previous_chunk) => {
545+
assert_eq!(previous_chunk.identifier, 7);
546+
assert!(previous_chunk.previous.is_none());
547+
assert_matches!(previous_chunk.next, Some(next) => {
548+
assert_eq!(next, 42);
549+
});
550+
assert_matches!(previous_chunk.content, ChunkContent::Items(items) => {
551+
assert_eq!(items.len(), 2);
552+
check_test_event(&items[0], "brigand du jorat");
553+
check_test_event(&items[1], "morbier");
554+
});
555+
});
556+
}
557+
505558
/// Macro for generating tests for IndexedDB implementation of
506559
/// [`EventCacheStore`]
507560
///
@@ -621,6 +674,13 @@ macro_rules! indexeddb_event_cache_store_integration_tests {
621674
$crate::event_cache_store::integration_tests::test_load_last_chunk(store)
622675
.await
623676
}
677+
678+
#[async_test]
679+
async fn test_load_previous_chunk() {
680+
let store = get_event_cache_store().await.expect("Failed to get event cache store");
681+
$crate::event_cache_store::integration_tests::test_load_previous_chunk(store)
682+
.await
683+
}
624684
}
625685
};
626686
}
@@ -654,6 +714,13 @@ macro_rules! event_cache_store_integration_tests {
654714
event_cache_store.test_handle_updates_and_rebuild_linked_chunk().await;
655715
}
656716

717+
#[async_test]
718+
async fn test_linked_chunk_incremental_loading() {
719+
let event_cache_store =
720+
get_event_cache_store().await.unwrap().into_event_cache_store();
721+
event_cache_store.test_linked_chunk_incremental_loading().await;
722+
}
723+
657724
#[async_test]
658725
async fn test_rebuild_empty_linked_chunk() {
659726
let event_cache_store =

crates/matrix-sdk-indexeddb/src/event_cache_store/mod.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,19 @@ impl_event_cache_store! {
353353
linked_chunk_id: LinkedChunkId<'_>,
354354
before_chunk_identifier: ChunkIdentifier,
355355
) -> Result<Option<RawChunk<Event, Gap>>, IndexeddbEventCacheStoreError> {
356-
self.memory_store
357-
.load_previous_chunk(linked_chunk_id, before_chunk_identifier)
358-
.await
359-
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
356+
let linked_chunk_id = linked_chunk_id.to_owned();
357+
let room_id = linked_chunk_id.room_id();
358+
let transaction = self.transaction(
359+
&[keys::LINKED_CHUNKS, keys::EVENTS, keys::GAPS],
360+
IdbTransactionMode::Readonly,
361+
)?;
362+
if let Some(chunk) = transaction.get_chunk_by_id(room_id, &before_chunk_identifier).await? {
363+
if let Some(previous_identifier) = chunk.previous {
364+
let previous_identifier = ChunkIdentifier::new(previous_identifier);
365+
return Ok(transaction.load_chunk_by_id(room_id, &previous_identifier).await?);
366+
}
367+
}
368+
Ok(None)
360369
}
361370

362371
async fn clear_all_linked_chunks(&self) -> Result<(), IndexeddbEventCacheStoreError> {

0 commit comments

Comments
 (0)