diff --git a/crates/matrix-sdk-base/src/event_cache/store/integration_tests.rs b/crates/matrix-sdk-base/src/event_cache/store/integration_tests.rs index 10651d446d9..de2174c2f0a 100644 --- a/crates/matrix-sdk-base/src/event_cache/store/integration_tests.rs +++ b/crates/matrix-sdk-base/src/event_cache/store/integration_tests.rs @@ -21,9 +21,7 @@ use matrix_sdk_common::{ AlgorithmInfo, DecryptedRoomEvent, EncryptionInfo, SyncTimelineEvent, TimelineEventKind, VerificationState, }, - linked_chunk::{ - ChunkContent, LinkedChunk, LinkedChunkBuilder, Position, RawLinkedChunk, Update, - }, + linked_chunk::{ChunkContent, LinkedChunk, LinkedChunkBuilder, Position, RawChunk, Update}, }; use matrix_sdk_test::{event_factory::EventFactory, ALICE, DEFAULT_TEST_ROOM_ID}; use ruma::{ @@ -121,9 +119,7 @@ pub trait EventCacheStoreIntegrationTests { async fn test_clear_all_rooms_chunks(&self); } -fn rebuild_linked_chunk( - raws: Vec>, -) -> Option> { +fn rebuild_linked_chunk(raws: Vec>) -> Option> { LinkedChunkBuilder::from_raw_parts(raws).build().unwrap() } diff --git a/crates/matrix-sdk-base/src/event_cache/store/memory_store.rs b/crates/matrix-sdk-base/src/event_cache/store/memory_store.rs index 02aeba58fe1..60ce6806d46 100644 --- a/crates/matrix-sdk-base/src/event_cache/store/memory_store.rs +++ b/crates/matrix-sdk-base/src/event_cache/store/memory_store.rs @@ -16,7 +16,7 @@ use std::{collections::HashMap, num::NonZeroUsize, sync::RwLock as StdRwLock, ti use async_trait::async_trait; use matrix_sdk_common::{ - linked_chunk::{relational::RelationalLinkedChunk, RawLinkedChunk, Update}, + linked_chunk::{relational::RelationalLinkedChunk, RawChunk, Update}, ring_buffer::RingBuffer, store_locks::memory_store_helper::try_take_leased_lock, }; @@ -96,7 +96,7 @@ impl EventCacheStore for MemoryStore { async fn reload_linked_chunk( &self, room_id: &RoomId, - ) -> Result>, Self::Error> { + ) -> Result>, Self::Error> { let inner = self.inner.read().unwrap(); inner .events diff --git a/crates/matrix-sdk-base/src/event_cache/store/traits.rs b/crates/matrix-sdk-base/src/event_cache/store/traits.rs index 4251eb8987e..5eb66d5fbba 100644 --- a/crates/matrix-sdk-base/src/event_cache/store/traits.rs +++ b/crates/matrix-sdk-base/src/event_cache/store/traits.rs @@ -16,7 +16,7 @@ use std::{fmt, sync::Arc}; use async_trait::async_trait; use matrix_sdk_common::{ - linked_chunk::{RawLinkedChunk, Update}, + linked_chunk::{RawChunk, Update}, AsyncTraitDeps, }; use ruma::{MxcUri, RoomId}; @@ -62,7 +62,7 @@ pub trait EventCacheStore: AsyncTraitDeps { async fn reload_linked_chunk( &self, room_id: &RoomId, - ) -> Result>, Self::Error>; + ) -> Result>, Self::Error>; /// Clear persisted events for all the rooms. /// @@ -192,7 +192,7 @@ impl EventCacheStore for EraseEventCacheStoreError { async fn reload_linked_chunk( &self, room_id: &RoomId, - ) -> Result>, Self::Error> { + ) -> Result>, Self::Error> { self.0.reload_linked_chunk(room_id).await.map_err(Into::into) } diff --git a/crates/matrix-sdk-common/src/linked_chunk/builder.rs b/crates/matrix-sdk-common/src/linked_chunk/builder.rs index 0bcb3e20f31..81459e2d605 100644 --- a/crates/matrix-sdk-common/src/linked_chunk/builder.rs +++ b/crates/matrix-sdk-common/src/linked_chunk/builder.rs @@ -21,7 +21,7 @@ use tracing::error; use super::{ Chunk, ChunkContent, ChunkIdentifier, ChunkIdentifierGenerator, Ends, LinkedChunk, - ObservableUpdates, RawLinkedChunk, + ObservableUpdates, RawChunk, }; /// A temporary chunk representation in the [`LinkedChunkBuilder`]. @@ -262,15 +262,15 @@ impl LinkedChunkBuilder { } /// Fills a linked chunk builder from all the given raw parts. - pub fn from_raw_parts(raws: Vec>) -> Self { + pub fn from_raw_parts(raws: Vec>) -> Self { let mut this = Self::new(); for raw in raws { match raw.content { ChunkContent::Gap(gap) => { - this.push_gap(raw.previous, raw.id, raw.next, gap); + this.push_gap(raw.previous, raw.identifier, raw.next, gap); } ChunkContent::Items(vec) => { - this.push_items(raw.previous, raw.id, raw.next, vec); + this.push_items(raw.previous, raw.identifier, raw.next, vec); } } } diff --git a/crates/matrix-sdk-common/src/linked_chunk/mod.rs b/crates/matrix-sdk-common/src/linked_chunk/mod.rs index faf92ef2b09..6a67383b014 100644 --- a/crates/matrix-sdk-common/src/linked_chunk/mod.rs +++ b/crates/matrix-sdk-common/src/linked_chunk/mod.rs @@ -1064,7 +1064,7 @@ impl<'a, const CAP: usize, Item, Gap> Iterator for Iter<'a, CAP, Item, Gap> { } /// This enum represents the content of a [`Chunk`]. -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum ChunkContent { /// The chunk represents a gap in the linked chunk, i.e. a hole. It /// means that some items are missing in this location. @@ -1074,15 +1074,6 @@ pub enum ChunkContent { Items(Vec), } -impl Clone for ChunkContent { - fn clone(&self) -> Self { - match self { - Self::Gap(gap) => Self::Gap(gap.clone()), - Self::Items(items) => Self::Items(items.clone()), - } - } -} - /// A chunk is a node in the [`LinkedChunk`]. pub struct Chunk { /// The previous chunk. @@ -1429,8 +1420,12 @@ impl EmptyChunk { } /// The raw representation of a linked chunk, as persisted in storage. -#[derive(Debug)] -pub struct RawLinkedChunk { +/// +/// It may rebuilt into [`Chunk`] and shares the same internal representation, +/// except that links are materialized using [`ChunkIdentifier`] instead of raw +/// pointers to the previous and next chunks. +#[derive(Clone, Debug)] +pub struct RawChunk { /// Content section of the linked chunk. pub content: ChunkContent, @@ -1438,23 +1433,12 @@ pub struct RawLinkedChunk { pub previous: Option, /// Current chunk's identifier. - pub id: ChunkIdentifier, + pub identifier: ChunkIdentifier, /// Link to the next chunk, via its identifier. pub next: Option, } -impl Clone for RawLinkedChunk { - fn clone(&self) -> Self { - Self { - content: self.content.clone(), - previous: self.previous, - id: self.id, - next: self.next, - } - } -} - #[cfg(test)] mod tests { use std::{ diff --git a/crates/matrix-sdk-common/src/linked_chunk/relational.rs b/crates/matrix-sdk-common/src/linked_chunk/relational.rs index e823e927cfc..ec3e297de48 100644 --- a/crates/matrix-sdk-common/src/linked_chunk/relational.rs +++ b/crates/matrix-sdk-common/src/linked_chunk/relational.rs @@ -17,7 +17,7 @@ use ruma::{OwnedRoomId, RoomId}; -use super::{ChunkContent, RawLinkedChunk}; +use super::{ChunkContent, RawChunk}; use crate::linked_chunk::{ChunkIdentifier, Position, Update}; /// A row of the [`RelationalLinkedChunk::chunks`]. @@ -290,10 +290,7 @@ where /// /// Return an error result if the data was malformed in the struct, with a /// string message explaining details about the error. - pub fn reload_chunks( - &self, - room_id: &RoomId, - ) -> Result>, String> { + pub fn reload_chunks(&self, room_id: &RoomId) -> Result>, String> { let mut result = Vec::new(); for chunk_row in self.chunks.iter().filter(|chunk| chunk.room_id == room_id) { @@ -310,10 +307,10 @@ where let Some(first) = items.peek() else { // The only possibility is that we created an empty items chunk; mark it as // such, and continue. - result.push(RawLinkedChunk { + result.push(RawChunk { content: ChunkContent::Items(Vec::new()), previous: chunk_row.previous_chunk, - id: chunk_row.chunk, + identifier: chunk_row.chunk, next: chunk_row.next_chunk, }); continue; @@ -340,12 +337,12 @@ where // Sort them by their position. collected_items.sort_unstable_by_key(|(_item, index)| *index); - result.push(RawLinkedChunk { + result.push(RawChunk { content: ChunkContent::Items( collected_items.into_iter().map(|(item, _index)| item).collect(), ), previous: chunk_row.previous_chunk, - id: chunk_row.chunk, + identifier: chunk_row.chunk, next: chunk_row.next_chunk, }); } @@ -361,10 +358,10 @@ where )); } - result.push(RawLinkedChunk { + result.push(RawChunk { content: ChunkContent::Gap(gap.clone()), previous: chunk_row.previous_chunk, - id: chunk_row.chunk, + identifier: chunk_row.chunk, next: chunk_row.next_chunk, }); } diff --git a/crates/matrix-sdk-sqlite/src/event_cache_store.rs b/crates/matrix-sdk-sqlite/src/event_cache_store.rs index f78e3c1c8c8..33baf630b41 100644 --- a/crates/matrix-sdk-sqlite/src/event_cache_store.rs +++ b/crates/matrix-sdk-sqlite/src/event_cache_store.rs @@ -22,7 +22,7 @@ use async_trait::async_trait; use deadpool_sqlite::{Object as SqliteAsyncConn, Pool as SqlitePool, Runtime}; use matrix_sdk_base::{ event_cache::{store::EventCacheStore, Event, Gap}, - linked_chunk::{ChunkContent, ChunkIdentifier, RawLinkedChunk, Update}, + linked_chunk::{ChunkContent, ChunkIdentifier, RawChunk, Update}, media::{MediaRequestParameters, UniqueKey}, }; use matrix_sdk_store_encryption::StoreCipher; @@ -148,7 +148,7 @@ impl SqliteEventCacheStore { &self, room_id: &RoomId, chunk_id: ChunkIdentifier, - ) -> Result> { + ) -> Result> { let hashed_room_id = self.encode_key(keys::LINKED_CHUNKS, room_id); let this = self.clone(); @@ -176,7 +176,7 @@ trait TransactionExtForLinkedChunks { index: u64, next: Option, chunk_type: &str, - ) -> Result>; + ) -> Result>; fn load_gap_content( &self, @@ -202,7 +202,7 @@ impl TransactionExtForLinkedChunks for Transaction<'_> { id: u64, next: Option, chunk_type: &str, - ) -> Result> { + ) -> Result> { let previous = previous.map(ChunkIdentifier::new); let next = next.map(ChunkIdentifier::new); let id = ChunkIdentifier::new(id); @@ -212,13 +212,18 @@ impl TransactionExtForLinkedChunks for Transaction<'_> { // It's a gap! There's at most one row for it in the database, so a // call to `query_row` is sufficient. let gap = self.load_gap_content(store, room_id, id)?; - Ok(RawLinkedChunk { content: ChunkContent::Gap(gap), previous, id, next }) + Ok(RawChunk { content: ChunkContent::Gap(gap), previous, identifier: id, next }) } CHUNK_TYPE_EVENT_TYPE_STRING => { // It's events! let events = self.load_events_content(store, room_id, id)?; - Ok(RawLinkedChunk { content: ChunkContent::Items(events), previous, id, next }) + Ok(RawChunk { + content: ChunkContent::Items(events), + previous, + identifier: id, + next, + }) } other => { @@ -537,7 +542,7 @@ impl EventCacheStore for SqliteEventCacheStore { async fn reload_linked_chunk( &self, room_id: &RoomId, - ) -> Result>, Self::Error> { + ) -> Result>, Self::Error> { let room_id = room_id.to_owned(); let hashed_room_id = self.encode_key(keys::LINKED_CHUNKS, &room_id); @@ -904,7 +909,7 @@ mod tests { { // Chunks are ordered from smaller to bigger IDs. let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(13)); + assert_eq!(c.identifier, ChunkIdentifier::new(13)); assert_eq!(c.previous, Some(ChunkIdentifier::new(42))); assert_eq!(c.next, Some(ChunkIdentifier::new(37))); assert_matches!(c.content, ChunkContent::Items(events) => { @@ -912,7 +917,7 @@ mod tests { }); let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(37)); + assert_eq!(c.identifier, ChunkIdentifier::new(37)); assert_eq!(c.previous, Some(ChunkIdentifier::new(13))); assert_eq!(c.next, None); assert_matches!(c.content, ChunkContent::Items(events) => { @@ -920,7 +925,7 @@ mod tests { }); let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(42)); + assert_eq!(c.identifier, ChunkIdentifier::new(42)); assert_eq!(c.previous, None); assert_eq!(c.next, Some(ChunkIdentifier::new(13))); assert_matches!(c.content, ChunkContent::Items(events) => { @@ -954,7 +959,7 @@ mod tests { // Chunks are ordered from smaller to bigger IDs. let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(42)); + assert_eq!(c.identifier, ChunkIdentifier::new(42)); assert_eq!(c.previous, None); assert_eq!(c.next, None); assert_matches!(c.content, ChunkContent::Gap(gap) => { @@ -1002,7 +1007,7 @@ mod tests { // Chunks are ordered from smaller to bigger IDs. let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(42)); + assert_eq!(c.identifier, ChunkIdentifier::new(42)); assert_eq!(c.previous, None); assert_eq!(c.next, Some(ChunkIdentifier::new(44))); assert_matches!(c.content, ChunkContent::Gap(gap) => { @@ -1010,7 +1015,7 @@ mod tests { }); let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(44)); + assert_eq!(c.identifier, ChunkIdentifier::new(44)); assert_eq!(c.previous, Some(ChunkIdentifier::new(42))); assert_eq!(c.next, None); assert_matches!(c.content, ChunkContent::Gap(gap) => { @@ -1074,7 +1079,7 @@ mod tests { assert_eq!(chunks.len(), 1); let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(42)); + assert_eq!(c.identifier, ChunkIdentifier::new(42)); assert_eq!(c.previous, None); assert_eq!(c.next, None); assert_matches!(c.content, ChunkContent::Items(events) => { @@ -1119,7 +1124,7 @@ mod tests { assert_eq!(chunks.len(), 1); let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(42)); + assert_eq!(c.identifier, ChunkIdentifier::new(42)); assert_eq!(c.previous, None); assert_eq!(c.next, None); assert_matches!(c.content, ChunkContent::Items(events) => { @@ -1178,7 +1183,7 @@ mod tests { assert_eq!(chunks.len(), 1); let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(42)); + assert_eq!(c.identifier, ChunkIdentifier::new(42)); assert_eq!(c.previous, None); assert_eq!(c.next, None); assert_matches!(c.content, ChunkContent::Items(events) => { @@ -1225,7 +1230,7 @@ mod tests { assert_eq!(chunks.len(), 1); let c = chunks.remove(0); - assert_eq!(c.id, ChunkIdentifier::new(42)); + assert_eq!(c.identifier, ChunkIdentifier::new(42)); assert_eq!(c.previous, None); assert_eq!(c.next, None); assert_matches!(c.content, ChunkContent::Items(events) => { diff --git a/crates/matrix-sdk/src/event_cache/room/mod.rs b/crates/matrix-sdk/src/event_cache/room/mod.rs index 626230d842d..21e29594b8f 100644 --- a/crates/matrix-sdk/src/event_cache/room/mod.rs +++ b/crates/matrix-sdk/src/event_cache/room/mod.rs @@ -585,7 +585,7 @@ mod private { }, Event, Gap, }, - linked_chunk::{ChunkContent, LinkedChunk, LinkedChunkBuilder, RawLinkedChunk, Update}, + linked_chunk::{ChunkContent, LinkedChunk, LinkedChunkBuilder, RawChunk, Update}, }; use once_cell::sync::OnceCell; use ruma::{serde::Raw, OwnedRoomId, RoomId}; @@ -800,13 +800,12 @@ mod private { } /// Create a debug string over multiple lines (one String per line), - /// offering a debug representation of a [`RawLinkedChunk`] loaded from - /// disk. - fn raw_chunks_debug_string(mut raw_chunks: Vec>) -> Vec { + /// offering a debug representation of a [`RawChunk`] loaded from disk. + fn raw_chunks_debug_string(mut raw_chunks: Vec>) -> Vec { let mut result = Vec::new(); // Sort the chunks by id, for the output to be deterministic. - raw_chunks.sort_by_key(|c| c.id.index()); + raw_chunks.sort_by_key(|c| c.identifier.index()); for c in raw_chunks { let content = match c.content { @@ -831,7 +830,8 @@ mod private { c.previous.map_or_else(|| "".to_owned(), |prev| prev.index().to_string()); let next = c.next.map_or_else(|| "".to_owned(), |prev| prev.index().to_string()); - let line = format!("chunk #{} (prev={prev}, next={next}): {content}", c.id.index()); + let line = + format!("chunk #{} (prev={prev}, next={next}): {content}", c.identifier.index()); result.push(line); } @@ -843,7 +843,7 @@ mod private { mod tests { use matrix_sdk_base::{ event_cache::Gap, - linked_chunk::{ChunkContent, ChunkIdentifier as CId, RawLinkedChunk}, + linked_chunk::{ChunkContent, ChunkIdentifier as CId, RawChunk}, }; use matrix_sdk_test::{event_factory::EventFactory, ALICE, DEFAULT_TEST_ROOM_ID}; use ruma::event_id; @@ -855,19 +855,19 @@ mod private { let mut raws = Vec::new(); let f = EventFactory::new().room(&DEFAULT_TEST_ROOM_ID).sender(*ALICE); - raws.push(RawLinkedChunk { + raws.push(RawChunk { content: ChunkContent::Items(vec![ f.text_msg("hey").event_id(event_id!("$1")).into_sync(), f.text_msg("you").event_id(event_id!("$2")).into_sync(), ]), - id: CId::new(1), + identifier: CId::new(1), previous: Some(CId::new(0)), next: None, }); - raws.push(RawLinkedChunk { + raws.push(RawChunk { content: ChunkContent::Gap(Gap { prev_token: "prev-token".to_owned() }), - id: CId::new(0), + identifier: CId::new(0), previous: None, next: Some(CId::new(1)), });