Skip to content

Commit 47b73c7

Browse files
committed
WIP
1 parent ada4373 commit 47b73c7

File tree

5 files changed

+169
-55
lines changed

5 files changed

+169
-55
lines changed

crates/matrix-sdk-ui/src/timeline/builder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,10 @@ async fn room_event_cache_updates_task(
430430
.await;
431431
}
432432
}
433+
434+
RoomEventCacheUpdate::UpdateThreadSummaries { summaries: _summaries } => {
435+
// TODO: see you later alligator
436+
}
433437
}
434438
}
435439
}

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ use matrix_sdk_base::{
4444
sync::RoomUpdates,
4545
};
4646
use matrix_sdk_common::executor::{spawn, JoinHandle};
47-
use room::RoomEventCacheState;
47+
use room::{
48+
threads::{EventCacheThreadError, ThreadSummary},
49+
RoomEventCacheState,
50+
};
4851
use ruma::{
4952
events::AnySyncEphemeralRoomEvent, serde::Raw, OwnedEventId, OwnedRoomId, RoomId, RoomVersionId,
5053
};
@@ -104,6 +107,10 @@ pub enum EventCacheError {
104107
/// [`LinkedChunk`]: matrix_sdk_common::linked_chunk::LinkedChunk
105108
#[error(transparent)]
106109
LinkedChunkLoader(#[from] LazyLoaderError),
110+
111+
/// An error happened while handling thread updates for this room.
112+
#[error(transparent)]
113+
Thread(#[from] EventCacheThreadError),
107114
}
108115

109116
/// A result using the [`EventCacheError`].
@@ -603,6 +610,13 @@ pub enum RoomEventCacheUpdate {
603610
origin: EventsOrigin,
604611
},
605612

613+
/// The room received new information in threads, and some thread summaries
614+
/// have been updated as a result of that.
615+
UpdateThreadSummaries {
616+
/// Mapping from the thread root event ID to the thread summary.
617+
summaries: BTreeMap<OwnedEventId, ThreadSummary>,
618+
},
619+
606620
/// The room has received new ephemeral events.
607621
AddEphemeralEvents {
608622
/// XXX: this is temporary, until read receipts are handled in the event

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

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ impl RoomEventCacheInner {
378378
ambiguity_changes: BTreeMap<OwnedEventId, AmbiguityChange>,
379379
) -> Result<()> {
380380
let mut prev_batch = timeline.prev_batch;
381+
381382
if timeline.events.is_empty()
382383
&& prev_batch.is_none()
383384
&& ephemeral_events.is_empty()
@@ -410,6 +411,17 @@ impl RoomEventCacheInner {
410411
all_duplicates,
411412
) = state.collect_valid_and_duplicated_events(timeline.events).await?;
412413

414+
// If we only received duplicated events, we don't need to store the gap: if
415+
// there was a gap, we'd have received an unknown event at the tail of
416+
// the room's timeline (unless the server reordered sync events since the last
417+
// time we sync'd).
418+
if all_duplicates {
419+
prev_batch = None;
420+
}
421+
422+
// Handle the thread updates separately.
423+
let thread_updates = state.handle_live_threads(&timeline.events, prev_batch.is_some())?;
424+
413425
// During a sync, when a duplicated event is found, the old event is removed and
414426
// the new event is added.
415427
//
@@ -431,27 +443,20 @@ impl RoomEventCacheInner {
431443
// events themselves.
432444
let new_timeline_event_diffs = state
433445
.with_events_mut(|room_events| {
434-
// If we only received duplicated events, we don't need to store the gap: if
435-
// there was a gap, we'd have received an unknown event at the tail of
436-
// the room's timeline (unless the server reordered sync events since the last
437-
// time we sync'd).
438-
if !all_duplicates {
439-
if let Some(prev_token) = &prev_batch {
440-
// As a tiny optimization: remove the last chunk if it's an empty event
441-
// one, as it's not useful to keep it before a gap.
442-
let prev_chunk_to_remove =
443-
room_events.rchunks().next().and_then(|chunk| {
444-
(chunk.is_items() && chunk.num_items() == 0)
445-
.then_some(chunk.identifier())
446-
});
447-
448-
room_events.push_gap(Gap { prev_token: prev_token.clone() });
449-
450-
if let Some(prev_chunk_to_remove) = prev_chunk_to_remove {
451-
room_events.remove_empty_chunk_at(prev_chunk_to_remove).expect(
452-
"we just checked the chunk is there, and it's an empty item chunk",
453-
);
454-
}
446+
if let Some(prev_token) = &prev_batch {
447+
// As a tiny optimization: remove the last chunk if it's an empty event
448+
// one, as it's not useful to keep it before a gap.
449+
let prev_chunk_to_remove = room_events.rchunks().next().and_then(|chunk| {
450+
(chunk.is_items() && chunk.num_items() == 0)
451+
.then_some(chunk.identifier())
452+
});
453+
454+
room_events.push_gap(Gap { prev_token: prev_token.clone() });
455+
456+
if let Some(prev_chunk_to_remove) = prev_chunk_to_remove {
457+
room_events.remove_empty_chunk_at(prev_chunk_to_remove).expect(
458+
"we just checked the chunk is there, and it's an empty item chunk",
459+
);
455460
}
456461
}
457462

@@ -496,6 +501,12 @@ impl RoomEventCacheInner {
496501
});
497502
}
498503

504+
if !thread_updates.is_empty() {
505+
let _ = self.sender.send(RoomEventCacheUpdate::UpdateThreadSummaries {
506+
summaries: thread_updates,
507+
});
508+
}
509+
499510
if !ephemeral_events.is_empty() {
500511
let _ = self
501512
.sender
@@ -539,7 +550,7 @@ pub(super) enum LoadMoreEventsBackwardsOutcome {
539550
// Use a private module to hide `events` to this parent module.
540551
mod private {
541552
use std::{
542-
collections::HashSet,
553+
collections::{BTreeMap, HashSet},
543554
sync::{atomic::AtomicUsize, Arc},
544555
};
545556

@@ -568,7 +579,9 @@ mod private {
568579
EventCacheError,
569580
},
570581
events::RoomEvents,
571-
sort_positions_descending, EventLocation, LoadMoreEventsBackwardsOutcome,
582+
sort_positions_descending,
583+
threads::{EventCacheThreadError, RoomThreads, ThreadSummary},
584+
EventLocation, LoadMoreEventsBackwardsOutcome,
572585
};
573586
use crate::event_cache::RoomPaginationStatus;
574587

@@ -589,6 +602,9 @@ mod private {
589602
/// The events of the room.
590603
events: RoomEvents,
591604

605+
/// All the information about threads from this room.
606+
threads: RoomThreads,
607+
592608
/// The events deduplicator instance to help finding duplicates.
593609
deduplicator: Deduplicator,
594610

@@ -647,10 +663,13 @@ mod private {
647663
let events = RoomEvents::with_initial_linked_chunk(linked_chunk);
648664
let deduplicator = Deduplicator::new(room_id.clone(), store.clone());
649665

666+
let threads = RoomThreads::new();
667+
650668
Ok(Self {
651669
room: room_id,
652670
room_version,
653671
store,
672+
threads,
654673
events,
655674
deduplicator,
656675
waited_for_initial_prev_token: false,
@@ -1191,6 +1210,16 @@ mod private {
11911210
Ok(updates_as_vector_diffs)
11921211
}
11931212

1213+
/// Handle new events from a sync, for threads.
1214+
#[instrument(skip_all, fields(room_id = %self.room))]
1215+
pub fn handle_live_threads(
1216+
&mut self,
1217+
events: &[TimelineEvent],
1218+
is_gappy: bool,
1219+
) -> Result<BTreeMap<OwnedEventId, ThreadSummary>, EventCacheThreadError> {
1220+
self.threads.handle_live(events, is_gappy)
1221+
}
1222+
11941223
/// If the given event is a redaction, try to retrieve the
11951224
/// to-be-redacted event in the chunk, and replace it by the
11961225
/// redacted form.

0 commit comments

Comments
 (0)