Skip to content

Commit 6ee2919

Browse files
committed
event cache: add EventCache::event() to get an event by id
1 parent b0f60d2 commit 6ee2919

File tree

1 file changed

+77
-4
lines changed
  • crates/matrix-sdk/src/event_cache

1 file changed

+77
-4
lines changed

crates/matrix-sdk/src/event_cache/mod.rs

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use matrix_sdk_common::executor::{spawn, JoinHandle};
5656
use ruma::{
5757
events::{AnyRoomAccountDataEvent, AnySyncEphemeralRoomEvent},
5858
serde::Raw,
59-
OwnedEventId, OwnedRoomId, RoomId,
59+
EventId, OwnedEventId, OwnedRoomId, RoomId,
6060
};
6161
use tokio::sync::{
6262
broadcast::{error::RecvError, Receiver, Sender},
@@ -196,6 +196,23 @@ impl EventCache {
196196
Ok(())
197197
}
198198

199+
/// Try to find an event by its ID in all the rooms.
200+
// NOTE: this does a linear scan, so it could be slow. If performance
201+
// requires it, we could use a direct mapping of event id -> event, and keep it
202+
// in memory until we store it on disk (and this becomes a SQL query by id).
203+
pub async fn event(&self, event_id: &EventId) -> Option<SyncTimelineEvent> {
204+
let by_room = self.inner.by_room.read().await;
205+
for room in by_room.values() {
206+
let events = room.inner.events.read().await;
207+
for (_pos, event) in events.revents() {
208+
if event.event_id().as_deref() == Some(event_id) {
209+
return Some(event.clone());
210+
}
211+
}
212+
}
213+
None
214+
}
215+
199216
#[instrument(skip_all)]
200217
async fn ignore_user_list_update_task(
201218
inner: Arc<EventCacheInner>,
@@ -759,13 +776,13 @@ pub enum EventsOrigin {
759776
mod tests {
760777
use assert_matches2::assert_matches;
761778
use futures_util::FutureExt as _;
762-
use matrix_sdk_base::sync::JoinedRoomUpdate;
779+
use matrix_sdk_base::sync::{JoinedRoomUpdate, RoomUpdates, Timeline};
763780
use matrix_sdk_test::async_test;
764-
use ruma::{room_id, serde::Raw};
781+
use ruma::{event_id, room_id, serde::Raw, user_id};
765782
use serde_json::json;
766783

767784
use super::{EventCacheError, RoomEventCacheUpdate};
768-
use crate::test_utils::logged_in_client;
785+
use crate::test_utils::{assert_event_matches_msg, events::EventFactory, logged_in_client};
769786

770787
#[async_test]
771788
async fn test_must_explicitly_subscribe() {
@@ -828,4 +845,60 @@ mod tests {
828845

829846
assert!(stream.recv().now_or_never().is_none());
830847
}
848+
849+
#[async_test]
850+
async fn test_get_event_by_id() {
851+
let client = logged_in_client(None).await;
852+
let room1 = room_id!("!galette:saucisse.bzh");
853+
let room2 = room_id!("!crepe:saucisse.bzh");
854+
855+
let event_cache = client.event_cache();
856+
event_cache.subscribe().unwrap();
857+
858+
// Insert two rooms with a few events.
859+
let f = EventFactory::new().room(room1).sender(user_id!("@ben:saucisse.bzh"));
860+
861+
let eid1 = event_id!("$1");
862+
let eid2 = event_id!("$2");
863+
let eid3 = event_id!("$3");
864+
865+
let joined_room_update1 = JoinedRoomUpdate {
866+
timeline: Timeline {
867+
events: vec![
868+
f.text_msg("hey").event_id(eid1).into(),
869+
f.text_msg("you").event_id(eid2).into(),
870+
],
871+
..Default::default()
872+
},
873+
..Default::default()
874+
};
875+
876+
let joined_room_update2 = JoinedRoomUpdate {
877+
timeline: Timeline {
878+
events: vec![f.text_msg("bjr").event_id(eid3).into()],
879+
..Default::default()
880+
},
881+
..Default::default()
882+
};
883+
884+
let mut updates = RoomUpdates::default();
885+
updates.join.insert(room1.to_owned(), joined_room_update1);
886+
updates.join.insert(room2.to_owned(), joined_room_update2);
887+
888+
// Have the event cache handle them.
889+
event_cache.inner.handle_room_updates(updates).await.unwrap();
890+
891+
// Now retrieve all the events one by one.
892+
let found1 = event_cache.event(eid1).await.unwrap();
893+
assert_event_matches_msg(&found1, "hey");
894+
895+
let found2 = event_cache.event(eid2).await.unwrap();
896+
assert_event_matches_msg(&found2, "you");
897+
898+
let found3 = event_cache.event(eid3).await.unwrap();
899+
assert_event_matches_msg(&found3, "bjr");
900+
901+
// An unknown event won't be found.
902+
assert!(event_cache.event(event_id!("$unknown")).await.is_none());
903+
}
831904
}

0 commit comments

Comments
 (0)