@@ -39,7 +39,7 @@ use tokio::sync::{
39
39
broadcast:: { Receiver , Sender } ,
40
40
mpsc, Notify , RwLock ,
41
41
} ;
42
- use tracing:: { trace, warn} ;
42
+ use tracing:: { error , trace, warn} ;
43
43
44
44
use super :: {
45
45
deduplicator:: DeduplicationOutcome ,
@@ -182,21 +182,25 @@ impl RoomEventCache {
182
182
183
183
/// Try to find an event by id in this room.
184
184
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) ) =
186
198
self . inner . all_events . read ( ) . await . events . get ( event_id) . cloned ( )
187
199
{
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
198
203
}
199
- None
200
204
}
201
205
202
206
/// Try to find an event by id in this room, along with its related events.
@@ -662,7 +666,7 @@ mod private {
662
666
} ;
663
667
use matrix_sdk_common:: executor:: spawn;
664
668
use once_cell:: sync:: OnceCell ;
665
- use ruma:: { serde:: Raw , OwnedEventId , OwnedRoomId } ;
669
+ use ruma:: { serde:: Raw , EventId , OwnedEventId , OwnedRoomId } ;
666
670
use tracing:: { debug, error, instrument, trace} ;
667
671
668
672
use super :: {
@@ -1129,6 +1133,34 @@ mod private {
1129
1133
& self . events
1130
1134
}
1131
1135
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
+
1132
1164
/// Gives a temporary mutable handle to the underlying in-memory events,
1133
1165
/// and will propagate changes to the storage once done.
1134
1166
///
@@ -1651,33 +1683,33 @@ mod tests {
1651
1683
1652
1684
let ( items, mut stream) = room_event_cache. subscribe ( ) . await ;
1653
1685
1654
- // The rooms knows about some cached events.
1686
+ // The rooms knows about all cached events.
1655
1687
{
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( ) ) ;
1659
1689
assert ! ( room_event_cache. event( event_id2) . await . is_some( ) ) ;
1690
+ }
1660
1691
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.
1662
1695
assert_eq ! ( items. len( ) , 1 ) ;
1663
1696
assert_eq ! ( items[ 0 ] . event_id( ) . unwrap( ) , event_id2) ;
1664
1697
1665
1698
assert ! ( stream. is_empty( ) ) ;
1666
1699
}
1667
1700
1668
- // Let's load more chunks to get all events.
1701
+ // Let's load more chunks to load all events.
1669
1702
{
1670
1703
room_event_cache. pagination ( ) . run_backwards_once ( 20 ) . await . unwrap ( ) ;
1671
1704
1672
1705
assert_let_timeout ! (
1673
1706
Ok ( RoomEventCacheUpdate :: UpdateTimelineEvents { diffs, .. } ) = stream. recv( )
1674
1707
) ;
1675
1708
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
+ } ) ;
1681
1713
1682
1714
assert ! ( stream. is_empty( ) ) ;
1683
1715
}
@@ -1799,8 +1831,8 @@ mod tests {
1799
1831
assert_eq ! ( items[ 0 ] . event_id( ) . unwrap( ) , event_id2) ;
1800
1832
assert ! ( stream. is_empty( ) ) ;
1801
1833
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 ( ) ) ;
1804
1836
assert ! ( room_event_cache. event( event_id2) . await . is_some( ) ) ;
1805
1837
1806
1838
// Let's paginate to load more events.
@@ -1810,11 +1842,9 @@ mod tests {
1810
1842
Ok ( RoomEventCacheUpdate :: UpdateTimelineEvents { diffs, .. } ) = stream. recv( )
1811
1843
) ;
1812
1844
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
+ } ) ;
1818
1848
1819
1849
assert ! ( stream. is_empty( ) ) ;
1820
1850
0 commit comments