From ccd5e877eb3ff45b901a0b570e7d0fabd6668475 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 27 Jun 2023 16:05:26 +0200 Subject: [PATCH] feat: Cache the `RoomListService`'s rooms That avoids recreating a timeline object every time a user calls `RoomListService::room()` with the same room id, so that should speed up operations like fetching the latest event for rooms we've already entered before. --- crates/matrix-sdk-ui/src/room_list/mod.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/matrix-sdk-ui/src/room_list/mod.rs b/crates/matrix-sdk-ui/src/room_list/mod.rs index 5248430d5..e61462a68 100644 --- a/crates/matrix-sdk-ui/src/room_list/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list/mod.rs @@ -67,7 +67,7 @@ mod room; mod room_list; mod state; -use std::{future::ready, sync::Arc}; +use std::{collections::BTreeMap, future::ready, sync::Arc}; use async_stream::stream; use eyeball::{shared::Observable, Subscriber}; @@ -87,11 +87,14 @@ use ruma::{ }; pub use state::*; use thiserror::Error; +use tokio::sync::Mutex; /// The [`RoomListService`] type. See the module's documentation to learn more. #[derive(Debug)] pub struct RoomListService { sliding_sync: Arc, + /// Room cache, to avoid recreating `Room`s everytime users fetch them. + rooms: Arc>>, state: Observable, } @@ -155,7 +158,7 @@ impl RoomListService { .map(Arc::new) .map_err(Error::SlidingSync)?; - Ok(Self { sliding_sync, state: Observable::new(State::Init) }) + Ok(Self { sliding_sync, state: Observable::new(State::Init), rooms: Default::default() }) } /// Start to sync the room list. @@ -282,10 +285,17 @@ impl RoomListService { /// Get a [`Room`] if it exists. pub async fn room(&self, room_id: &RoomId) -> Result { - match self.sliding_sync.get_room(room_id).await { + let mut rooms = self.rooms.lock().await; + if let Some(room) = rooms.get(room_id) { + return Ok(room.clone()); + } + let room = match self.sliding_sync.get_room(room_id).await { Some(room) => Room::new(self.sliding_sync.clone(), room).await, None => Err(Error::RoomNotFound(room_id.to_owned())), - } + }; + let room = room?; + rooms.insert(room_id.to_owned(), room.clone()); + Ok(room) } #[cfg(any(test, feature = "testing"))]