Skip to content

Commit cc8bc05

Browse files
committed
refactor: RoomEvents::reset really clear the linked chunk.
This patch updates `RoomEvents::reset` to not drop the `LinkedChunk` to clear it.
1 parent 728d646 commit cc8bc05

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed

crates/matrix-sdk-common/src/linked_chunk/as_vector.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,9 +729,9 @@ mod tests {
729729
assert_eq!(chunks.len(), 1);
730730
assert_eq!(chunks[0].0, ChunkIdentifierGenerator::FIRST_IDENTIFIER);
731731
assert_eq!(chunks[0].1, 0);
732-
}
733732

734-
assert!(as_vector.take().is_empty());
733+
assert!(as_vector.take().is_empty());
734+
}
735735

736736
linked_chunk.push_items_back(['a', 'b', 'c', 'd']);
737737

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

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
use std::cmp::Ordering;
1616

17+
use eyeball_im::VectorDiff;
1718
pub use matrix_sdk_base::event_cache::{Event, Gap};
19+
use matrix_sdk_base::linked_chunk::AsVector;
1820
use matrix_sdk_common::linked_chunk::{
1921
Chunk, ChunkIdentifier, EmptyChunk, Error, Iter, LinkedChunk, Position,
2022
};
@@ -31,6 +33,11 @@ pub struct RoomEvents {
3133
/// The real in-memory storage for all the events.
3234
chunks: LinkedChunk<DEFAULT_CHUNK_CAPACITY, Event, Gap>,
3335

36+
/// Type mapping [`Update`]s from [`Self::chunks`] to [`VectorDiff`]s.
37+
///
38+
/// [`Update`]: matrix_sdk_base::linked_chunk::Update
39+
chunks_updates_as_vectordiffs: AsVector<Event, Gap>,
40+
3441
/// The events deduplicator instance to help finding duplicates.
3542
deduplicator: Deduplicator,
3643
}
@@ -44,12 +51,22 @@ impl Default for RoomEvents {
4451
impl RoomEvents {
4552
/// Build a new [`RoomEvents`] struct with zero events.
4653
pub fn new() -> Self {
47-
Self { chunks: LinkedChunk::new(), deduplicator: Deduplicator::new() }
54+
let mut chunks = LinkedChunk::new_with_update_history();
55+
let chunks_updates_as_vectordiffs = chunks
56+
.as_vector()
57+
// SAFETY: The `LinkedChunk` has been built with `new_with_update_history`, so
58+
// `as_vector` must return `Some(…)`.
59+
.expect("`LinkedChunk` must have been constructor with `new_with_update_history`");
60+
61+
Self { chunks, chunks_updates_as_vectordiffs, deduplicator: Deduplicator::new() }
4862
}
4963

5064
/// Clear all events.
65+
///
66+
/// All events, all gaps, everything is dropped, move into the void, into
67+
/// the ether, forever.
5168
pub fn reset(&mut self) {
52-
self.chunks = LinkedChunk::new();
69+
self.chunks.clear();
5370
}
5471

5572
/// Push events after all events or gaps.
@@ -158,6 +175,18 @@ impl RoomEvents {
158175
self.chunks.items()
159176
}
160177

178+
/// Get all updates from the room events as [`VectorDiff`].
179+
///
180+
/// Be careful that each `VectorDiff` is returned only once!
181+
///
182+
/// See [`AsVector`] to learn more.
183+
///
184+
/// [`Update`]: matrix_sdk_base::linked_chunk::Update
185+
#[allow(unused)] // gonna be useful very soon! but we need it now for test purposes
186+
pub fn updates_as_vector_diffs(&mut self) -> Vec<VectorDiff<Event>> {
187+
self.chunks_updates_as_vectordiffs.take()
188+
}
189+
161190
/// Deduplicate `events` considering all events in `Self::chunks`.
162191
///
163192
/// The returned tuple contains (i) the unique events, and (ii) the
@@ -315,6 +344,7 @@ impl RoomEvents {
315344

316345
#[cfg(test)]
317346
mod tests {
347+
use assert_matches::assert_matches;
318348
use assert_matches2::assert_let;
319349
use matrix_sdk_test::event_factory::EventFactory;
320350
use ruma::{user_id, EventId, OwnedEventId};
@@ -934,4 +964,57 @@ mod tests {
934964
// Ensure no chunk has been removed.
935965
assert_eq!(room_events.chunks().count(), 3);
936966
}
967+
968+
#[test]
969+
fn test_reset() {
970+
let (event_id_0, event_0) = new_event("$ev0");
971+
let (event_id_1, event_1) = new_event("$ev1");
972+
let (event_id_2, event_2) = new_event("$ev2");
973+
let (event_id_3, event_3) = new_event("$ev3");
974+
975+
// Push some events.
976+
let mut room_events = RoomEvents::new();
977+
room_events.push_events([event_0, event_1]);
978+
room_events.push_gap(Gap { prev_token: "raclette".to_owned() });
979+
room_events.push_events([event_2]);
980+
981+
// Read the updates as `VectorDiff`.
982+
let diffs = room_events.updates_as_vector_diffs();
983+
984+
assert_eq!(diffs.len(), 2);
985+
986+
assert_matches!(
987+
&diffs[0],
988+
VectorDiff::Append { values } => {
989+
assert_eq!(values.len(), 2);
990+
assert_eq!(values[0].event_id(), Some(event_id_0));
991+
assert_eq!(values[1].event_id(), Some(event_id_1));
992+
}
993+
);
994+
assert_matches!(
995+
&diffs[1],
996+
VectorDiff::Append { values } => {
997+
assert_eq!(values.len(), 1);
998+
assert_eq!(values[0].event_id(), Some(event_id_2));
999+
}
1000+
);
1001+
1002+
// Now we can reset and see what happens.
1003+
room_events.reset();
1004+
room_events.push_events([event_3]);
1005+
1006+
// Read the updates as `VectorDiff`.
1007+
let diffs = room_events.updates_as_vector_diffs();
1008+
1009+
assert_eq!(diffs.len(), 2);
1010+
1011+
assert_matches!(&diffs[0], VectorDiff::Clear);
1012+
assert_matches!(
1013+
&diffs[1],
1014+
VectorDiff::Append { values } => {
1015+
assert_eq!(values.len(), 1);
1016+
assert_eq!(values[0].event_id(), Some(event_id_3));
1017+
}
1018+
);
1019+
}
9371020
}

0 commit comments

Comments
 (0)