@@ -39,7 +39,7 @@ use tokio::sync::{
3939 broadcast:: { Receiver , Sender } ,
4040 mpsc, Notify , RwLock ,
4141} ;
42- use tracing:: { trace, warn} ;
42+ use tracing:: { error , trace, warn} ;
4343
4444use super :: {
4545 deduplicator:: DeduplicationOutcome ,
@@ -182,21 +182,25 @@ impl RoomEventCache {
182182
183183 /// Try to find an event by id in this room.
184184 pub async fn event ( & self , event_id : & EventId ) -> Option < TimelineEvent > {
185- if let Some ( ( room_id, event) ) =
185+ // Search in all loaded or stored events.
186+ let Ok ( maybe_position_and_event) = self . inner . state . read ( ) . await . find_event ( event_id) . await
187+ else {
188+ error ! ( "Failed to find the event" ) ;
189+
190+ return None ;
191+ } ;
192+
193+ if let Some ( event) = maybe_position_and_event. map ( |( _position, event) | event) {
194+ Some ( event)
195+ }
196+ // Search in `AllEventsCache` for known events that are not stored.
197+ else if let Some ( ( room_id, event) ) =
186198 self . inner . all_events . read ( ) . await . events . get ( event_id) . cloned ( )
187199 {
188- if room_id == self . inner . room_id {
189- return Some ( event) ;
190- }
191- }
192-
193- let state = self . inner . state . read ( ) . await ;
194- for ( _pos, event) in state. events ( ) . revents ( ) {
195- if event. event_id ( ) . as_deref ( ) == Some ( event_id) {
196- return Some ( event. clone ( ) ) ;
197- }
200+ ( room_id == self . inner . room_id ) . then_some ( event)
201+ } else {
202+ None
198203 }
199- None
200204 }
201205
202206 /// Try to find an event by id in this room, along with its related events.
@@ -662,7 +666,7 @@ mod private {
662666 } ;
663667 use matrix_sdk_common:: executor:: spawn;
664668 use once_cell:: sync:: OnceCell ;
665- use ruma:: { serde:: Raw , OwnedEventId , OwnedRoomId } ;
669+ use ruma:: { serde:: Raw , EventId , OwnedEventId , OwnedRoomId } ;
666670 use tracing:: { debug, error, instrument, trace} ;
667671
668672 use super :: {
@@ -1129,6 +1133,34 @@ mod private {
11291133 & self . events
11301134 }
11311135
1136+ /// Find a single event in this room.
1137+ ///
1138+ /// It starts by looking into loaded events in `RoomEvents` before
1139+ /// looking inside the storage if it is enabled.
1140+ pub async fn find_event (
1141+ & self ,
1142+ event_id : & EventId ,
1143+ ) -> Result < Option < ( Position , TimelineEvent ) > , EventCacheError > {
1144+ let room_id = self . room . as_ref ( ) ;
1145+
1146+ // There are supposedly fewer events loaded in memory than in the store. Let's
1147+ // start by looking up in the `RoomEvents`.
1148+ for ( position, event) in self . events ( ) . revents ( ) {
1149+ if event. event_id ( ) . as_deref ( ) == Some ( event_id) {
1150+ return Ok ( Some ( ( position, event. clone ( ) ) ) ) ;
1151+ }
1152+ }
1153+
1154+ let Some ( store) = self . store . get ( ) else {
1155+ // No store, event is not present.
1156+ return Ok ( None ) ;
1157+ } ;
1158+
1159+ let store = store. lock ( ) . await ?;
1160+
1161+ Ok ( store. find_event ( room_id, event_id) . await ?)
1162+ }
1163+
11321164 /// Gives a temporary mutable handle to the underlying in-memory events,
11331165 /// and will propagate changes to the storage once done.
11341166 ///
@@ -1651,33 +1683,33 @@ mod tests {
16511683
16521684 let ( items, mut stream) = room_event_cache. subscribe ( ) . await ;
16531685
1654- // The rooms knows about some cached events.
1686+ // The rooms knows about all cached events.
16551687 {
1656- // The chunk containing this event is not loaded yet
1657- assert ! ( room_event_cache. event( event_id1) . await . is_none( ) ) ;
1658- // The chunk containing this event **is** loaded.
1688+ assert ! ( room_event_cache. event( event_id1) . await . is_some( ) ) ;
16591689 assert ! ( room_event_cache. event( event_id2) . await . is_some( ) ) ;
1690+ }
16601691
1661- // The reloaded room must contain only one event.
1692+ // But only part of events are loaded from the store
1693+ {
1694+ // The room must contain only one event because only one chunk has been loaded.
16621695 assert_eq ! ( items. len( ) , 1 ) ;
16631696 assert_eq ! ( items[ 0 ] . event_id( ) . unwrap( ) , event_id2) ;
16641697
16651698 assert ! ( stream. is_empty( ) ) ;
16661699 }
16671700
1668- // Let's load more chunks to get all events.
1701+ // Let's load more chunks to load all events.
16691702 {
16701703 room_event_cache. pagination ( ) . run_backwards_once ( 20 ) . await . unwrap ( ) ;
16711704
16721705 assert_let_timeout ! (
16731706 Ok ( RoomEventCacheUpdate :: UpdateTimelineEvents { diffs, .. } ) = stream. recv( )
16741707 ) ;
16751708 assert_eq ! ( diffs. len( ) , 1 ) ;
1676- assert_matches ! ( & diffs[ 0 ] , VectorDiff :: Insert { index: 0 , value: _ } ) ;
1677-
1678- // The rooms knows about more cached events.
1679- assert ! ( room_event_cache. event( event_id1) . await . is_some( ) ) ;
1680- assert ! ( room_event_cache. event( event_id2) . await . is_some( ) ) ;
1709+ assert_matches ! ( & diffs[ 0 ] , VectorDiff :: Insert { index: 0 , value: event } => {
1710+ // Here you are `event_id1`!
1711+ assert_eq!( event. event_id( ) . unwrap( ) , event_id1) ;
1712+ } ) ;
16811713
16821714 assert ! ( stream. is_empty( ) ) ;
16831715 }
@@ -1799,8 +1831,8 @@ mod tests {
17991831 assert_eq ! ( items[ 0 ] . event_id( ) . unwrap( ) , event_id2) ;
18001832 assert ! ( stream. is_empty( ) ) ;
18011833
1802- // The event cache knows only one event .
1803- assert ! ( room_event_cache. event( event_id1) . await . is_none ( ) ) ;
1834+ // The event cache knows only all events though, even if they aren't loaded .
1835+ assert ! ( room_event_cache. event( event_id1) . await . is_some ( ) ) ;
18041836 assert ! ( room_event_cache. event( event_id2) . await . is_some( ) ) ;
18051837
18061838 // Let's paginate to load more events.
@@ -1810,11 +1842,9 @@ mod tests {
18101842 Ok ( RoomEventCacheUpdate :: UpdateTimelineEvents { diffs, .. } ) = stream. recv( )
18111843 ) ;
18121844 assert_eq ! ( diffs. len( ) , 1 ) ;
1813- assert_matches ! ( & diffs[ 0 ] , VectorDiff :: Insert { index: 0 , value: _ } ) ;
1814-
1815- // The event cache knows about the two events now!
1816- assert ! ( room_event_cache. event( event_id1) . await . is_some( ) ) ;
1817- assert ! ( room_event_cache. event( event_id2) . await . is_some( ) ) ;
1845+ assert_matches ! ( & diffs[ 0 ] , VectorDiff :: Insert { index: 0 , value: event } => {
1846+ assert_eq!( event. event_id( ) . unwrap( ) , event_id1) ;
1847+ } ) ;
18181848
18191849 assert ! ( stream. is_empty( ) ) ;
18201850
0 commit comments