From 85538dc3ed6a2d64fca6c838797513e245980b5e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 18 Mar 2024 15:17:25 +0100 Subject: [PATCH] feat(sdk): Remove `EventCacheStore`, `TimelineEntry`, `RoomInfo` and `MemoryStore`. --- crates/matrix-sdk/src/event_cache/mod.rs | 4 +- crates/matrix-sdk/src/event_cache/store.rs | 214 ++------------------- 2 files changed, 16 insertions(+), 202 deletions(-) diff --git a/crates/matrix-sdk/src/event_cache/mod.rs b/crates/matrix-sdk/src/event_cache/mod.rs index f43ce3c6b..435b79636 100644 --- a/crates/matrix-sdk/src/event_cache/mod.rs +++ b/crates/matrix-sdk/src/event_cache/mod.rs @@ -70,7 +70,7 @@ use tracing::{error, instrument, trace, warn}; use self::{ linked_chunk::ChunkContent, - store::{EventCacheStore, Gap, MemoryStore, PaginationToken, RoomEvents, TimelineEntry}, + store::{Gap, PaginationToken, RoomEvents}, }; use crate::{client::ClientInner, room::MessagesOptions, Client, Room}; @@ -767,7 +767,7 @@ mod tests { use matrix_sdk_test::{async_test, sync_timeline_event}; use ruma::room_id; - use super::{store::TimelineEntry, EventCacheError}; + use super::EventCacheError; use crate::{event_cache::store::PaginationToken, test_utils::logged_in_client}; #[async_test] diff --git a/crates/matrix-sdk/src/event_cache/store.rs b/crates/matrix-sdk/src/event_cache/store.rs index c0fe3b08e..a29d036ab 100644 --- a/crates/matrix-sdk/src/event_cache/store.rs +++ b/crates/matrix-sdk/src/event_cache/store.rs @@ -12,199 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{collections::BTreeMap, fmt, iter::once, result::Result as StdResult}; +use std::{fmt, iter::once, result::Result}; -use async_trait::async_trait; use matrix_sdk_common::deserialized_responses::SyncTimelineEvent; -use ruma::{OwnedRoomId, RoomId}; -use tokio::sync::RwLock; -use super::{ - linked_chunk::{ - Chunk, ChunkIdentifier, LinkedChunk, LinkedChunkError, LinkedChunkIter, - LinkedChunkIterBackward, Position, - }, - Result, +use super::linked_chunk::{ + Chunk, ChunkIdentifier, LinkedChunk, LinkedChunkError, LinkedChunkIter, + LinkedChunkIterBackward, Position, }; -/// A store that can be remember information about the event cache. -/// -/// It really acts as a cache, in the sense that clearing the backing data -/// should not have any irremediable effect, other than providing a lesser user -/// experience. -#[async_trait] -pub trait EventCacheStore: Send + Sync { - /// Returns all the known events for the given room. - async fn room_events(&self, room: &RoomId) -> Result>; - - /// Adds all the entries to the given room's timeline. - async fn append_room_entries(&self, room: &RoomId, entries: Vec) -> Result<()>; - - /// Returns whether the store knows about the given pagination token. - async fn contains_gap(&self, room: &RoomId, pagination_token: &PaginationToken) - -> Result; - - /// Replaces a given gap (identified by its pagination token) with the given - /// entries. - /// - /// Note: if the gap hasn't been found, then nothing happens, and the events - /// are lost. - /// - /// Returns whether the gap was found. - async fn replace_gap( - &self, - room: &RoomId, - gap_id: Option<&PaginationToken>, - entries: Vec, - ) -> Result; - - /// Retrieve the oldest backpagination token for the given room. - async fn oldest_backpagination_token(&self, room: &RoomId) -> Result>; - - /// Clear all the information tied to a given room. - /// - /// This forgets the following: - /// - events in the room - /// - pagination tokens - async fn clear_room(&self, room: &RoomId) -> Result<()>; -} - /// A newtype wrapper for a pagination token returned by a /messages response. #[derive(Clone, Debug, PartialEq)] pub struct PaginationToken(pub String); -#[derive(Clone)] -pub enum TimelineEntry { - Event(SyncTimelineEvent), - - Gap { - /// The token to use in the query, extracted from a previous "from" / - /// "end" field of a `/messages` response. - prev_token: PaginationToken, - }, -} - -/// All the information related to a room and stored in the event cache. -#[derive(Default)] -struct RoomInfo { - /// All the timeline entries per room, in sync order. - entries: Vec, -} - -impl RoomInfo { - fn clear(&mut self) { - self.entries.clear(); - } -} - -/// An [`EventCacheStore`] implementation that keeps all the information in -/// memory. -#[derive(Default)] -pub(crate) struct MemoryStore { - by_room: RwLock>, -} - -impl MemoryStore { - /// Create a new empty [`MemoryStore`]. - pub fn new() -> Self { - Default::default() - } -} - -#[async_trait] -impl EventCacheStore for MemoryStore { - async fn room_events(&self, room: &RoomId) -> Result> { - Ok(self - .by_room - .read() - .await - .get(room) - .map(|room_info| { - room_info - .entries - .iter() - .filter_map( - |entry| if let TimelineEntry::Event(ev) = entry { Some(ev) } else { None }, - ) - .cloned() - .collect() - }) - .unwrap_or_default()) - } - - async fn append_room_entries(&self, room: &RoomId, entries: Vec) -> Result<()> { - self.by_room.write().await.entry(room.to_owned()).or_default().entries.extend(entries); - Ok(()) - } - - async fn clear_room(&self, room: &RoomId) -> Result<()> { - // Clear the room, so as to avoid reallocations if the room is being reused. - // XXX: do we also want an actual way to *remove* a room? (for left rooms) - if let Some(room) = self.by_room.write().await.get_mut(room) { - room.clear(); - } - - Ok(()) - } - - async fn oldest_backpagination_token(&self, room: &RoomId) -> Result> { - Ok(self.by_room.read().await.get(room).and_then(|room| { - room.entries.iter().find_map(|entry| { - if let TimelineEntry::Gap { prev_token: backpagination_token } = entry { - Some(backpagination_token.clone()) - } else { - None - } - }) - })) - } - - async fn contains_gap(&self, room: &RoomId, needle: &PaginationToken) -> Result { - let mut by_room_guard = self.by_room.write().await; - let room = by_room_guard.entry(room.to_owned()).or_default(); - - Ok(room.entries.iter().any(|entry| { - if let TimelineEntry::Gap { prev_token: existing } = entry { - existing == needle - } else { - false - } - })) - } - - async fn replace_gap( - &self, - room: &RoomId, - token: Option<&PaginationToken>, - entries: Vec, - ) -> Result { - let mut by_room_guard = self.by_room.write().await; - let room = by_room_guard.entry(room.to_owned()).or_default(); - - if let Some(token) = token { - let gap_pos = room.entries.iter().enumerate().find_map(|(i, t)| { - if let TimelineEntry::Gap { prev_token: existing } = t { - if existing == token { - return Some(i); - } - } - None - }); - - if let Some(pos) = gap_pos { - room.entries.splice(pos..pos + 1, entries); - Ok(true) - } else { - Ok(false) - } - } else { - // We had no previous token: assume we can prepend the events. - room.entries.splice(0..0, entries); - Ok(true) - } - } -} - #[derive(Debug)] pub struct Gap { /// The token to use in the query, extracted from a previous "from" / @@ -266,7 +86,7 @@ impl RoomEvents { &mut self, events: I, position: Position, - ) -> StdResult<(), LinkedChunkError> + ) -> Result<(), LinkedChunkError> where I: IntoIterator, I::IntoIter: ExactSizeIterator, @@ -275,11 +95,7 @@ impl RoomEvents { } /// Insert a gap at a specified position. - pub fn insert_gap_at( - &mut self, - gap: Gap, - position: Position, - ) -> StdResult<(), LinkedChunkError> { + pub fn insert_gap_at(&mut self, gap: Gap, position: Position) -> Result<(), LinkedChunkError> { self.chunks.insert_gap_at(gap, position) } @@ -291,7 +107,7 @@ impl RoomEvents { &mut self, items: I, gap_identifier: ChunkIdentifier, - ) -> StdResult<(), LinkedChunkError> + ) -> Result<(), LinkedChunkError> where I: IntoIterator, I::IntoIter: ExactSizeIterator, @@ -335,7 +151,7 @@ impl RoomEvents { pub fn rchunks_from( &self, identifier: ChunkIdentifier, - ) -> StdResult< + ) -> Result< LinkedChunkIterBackward<'_, SyncTimelineEvent, Gap, DEFAULT_CHUNK_CAPACITY>, LinkedChunkError, > { @@ -347,10 +163,8 @@ impl RoomEvents { pub fn chunks_from( &self, identifier: ChunkIdentifier, - ) -> StdResult< - LinkedChunkIter<'_, SyncTimelineEvent, Gap, DEFAULT_CHUNK_CAPACITY>, - LinkedChunkError, - > { + ) -> Result, LinkedChunkError> + { self.chunks.chunks_from(identifier) } @@ -364,7 +178,7 @@ impl RoomEvents { /// Iterate over the events, forward. /// /// The oldest event comes first. - pub fn events(&self) -> impl Iterator { + pub fn events(&self) -> impl Iterator { self.chunks.items() } @@ -372,7 +186,7 @@ impl RoomEvents { pub fn revents_from( &self, position: Position, - ) -> StdResult, LinkedChunkError> { + ) -> Result, LinkedChunkError> { self.chunks.ritems_from(position) } @@ -381,13 +195,13 @@ impl RoomEvents { pub fn events_from( &self, position: Position, - ) -> StdResult, LinkedChunkError> { + ) -> Result, LinkedChunkError> { self.chunks.items_from(position) } } impl fmt::Debug for RoomEvents { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> StdResult<(), fmt::Error> { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { formatter.debug_struct("RoomEvents").field("chunk", &self.chunks).finish() } }