Skip to content

Commit

Permalink
refactor: RoomEvents::reset really clear the linked chunk.
Browse files Browse the repository at this point in the history
This patch updates `RoomEvents::reset` to not drop the `LinkedChunk` to
clear it.
  • Loading branch information
Hywan committed Nov 26, 2024
1 parent 2bcc71d commit 64e8114
Showing 1 changed file with 85 additions and 2 deletions.
87 changes: 85 additions & 2 deletions crates/matrix-sdk/src/event_cache/room/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

use std::cmp::Ordering;

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

/// Type mapping [`Update`]s from [`Self::chunks`] to [`VectorDiff`]s.
///
/// [`Update`]: matrix_sdk_base::linked_chunk::Update
chunks_updates_as_vectordiffs: AsVector<Event, Gap>,

/// The events deduplicator instance to help finding duplicates.
deduplicator: Deduplicator,
}
Expand All @@ -44,12 +51,22 @@ impl Default for RoomEvents {
impl RoomEvents {
/// Build a new [`RoomEvents`] struct with zero events.
pub fn new() -> Self {
Self { chunks: LinkedChunk::new(), deduplicator: Deduplicator::new() }
let mut chunks = LinkedChunk::new_with_update_history();
let chunks_updates_as_vectordiffs = chunks
.as_vector()
// SAFETY: The `LinkedChunk` has been built with `new_with_update_history`, so
// `as_vector` must return `Some(…)`.
.expect("`LinkedChunk` must have been constructor with `new_with_update_history`");

Self { chunks, chunks_updates_as_vectordiffs, deduplicator: Deduplicator::new() }
}

/// Clear all events.
///
/// All events, all gaps, everything is dropped, move into the void, into
/// the ether, forever.
pub fn reset(&mut self) {
self.chunks = LinkedChunk::new();
self.chunks.clear();
}

/// Push events after all events or gaps.
Expand Down Expand Up @@ -158,6 +175,18 @@ impl RoomEvents {
self.chunks.items()
}

/// Get all updates from the room events as [`VectorDiff`].
///
/// Be careful that each `VectorDiff` is returned only once!
///
/// See [`AsVector`] to learn more.
///
/// [`Update`]: matrix_sdk_base::linked_chunk::Update
#[allow(unused)] // gonna be useful very soon! but we need it now for test purposes
pub fn updates_as_vector_diffs(&mut self) -> Vec<VectorDiff<Event>> {
self.chunks_updates_as_vectordiffs.take()
}

/// Deduplicate `events` considering all events in `Self::chunks`.
///
/// The returned tuple contains (i) the unique events, and (ii) the
Expand Down Expand Up @@ -315,6 +344,7 @@ impl RoomEvents {

#[cfg(test)]
mod tests {
use assert_matches::assert_matches;
use assert_matches2::assert_let;
use matrix_sdk_test::event_factory::EventFactory;
use ruma::{user_id, EventId, OwnedEventId};
Expand Down Expand Up @@ -934,4 +964,57 @@ mod tests {
// Ensure no chunk has been removed.
assert_eq!(room_events.chunks().count(), 3);
}

#[test]
fn test_reset() {
let (event_id_0, event_0) = new_event("$ev0");
let (event_id_1, event_1) = new_event("$ev1");
let (event_id_2, event_2) = new_event("$ev2");
let (event_id_3, event_3) = new_event("$ev3");

// Push some events.
let mut room_events = RoomEvents::new();
room_events.push_events([event_0, event_1]);
room_events.push_gap(Gap { prev_token: "raclette".to_owned() });
room_events.push_events([event_2]);

// Read the updates as `VectorDiff`.
let diffs = room_events.updates_as_vector_diffs();

assert_eq!(diffs.len(), 2);

assert_matches!(
&diffs[0],
VectorDiff::Append { values } => {
assert_eq!(values.len(), 2);
assert_eq!(values[0].event_id(), Some(event_id_0));
assert_eq!(values[1].event_id(), Some(event_id_1));
}
);
assert_matches!(
&diffs[1],
VectorDiff::Append { values } => {
assert_eq!(values.len(), 1);
assert_eq!(values[0].event_id(), Some(event_id_2));
}
);

// Now we can reset and see what happens.
room_events.reset();
room_events.push_events([event_3]);

// Read the updates as `VectorDiff`.
let diffs = room_events.updates_as_vector_diffs();

assert_eq!(diffs.len(), 2);

assert_matches!(&diffs[0], VectorDiff::Clear);
assert_matches!(
&diffs[1],
VectorDiff::Append { values } => {
assert_eq!(values.len(), 1);
assert_eq!(values[0].event_id(), Some(event_id_3));
}
);
}
}

0 comments on commit 64e8114

Please sign in to comment.