-
Notifications
You must be signed in to change notification settings - Fork 289
feat(base): Add EventCacheStore::filter_duplicated_events
#4659
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,6 +123,9 @@ pub trait EventCacheStoreIntegrationTests { | |
|
||
/// Test that removing a room from storage empties all associated data. | ||
async fn test_remove_room(&self); | ||
|
||
/// Test that filtering duplicated events works as expected. | ||
async fn test_filter_duplicated_events(&self); | ||
} | ||
|
||
fn rebuild_linked_chunk(raws: Vec<RawChunk<Event, Gap>>) -> Option<LinkedChunk<3, Event, Gap>> { | ||
|
@@ -502,6 +505,79 @@ impl EventCacheStoreIntegrationTests for DynEventCacheStore { | |
let r1_linked_chunk = self.reload_linked_chunk(r1).await.unwrap(); | ||
assert!(!r1_linked_chunk.is_empty()); | ||
} | ||
|
||
async fn test_filter_duplicated_events(&self) { | ||
let room_id = room_id!("!r0:matrix.org"); | ||
let another_room_id = room_id!("!r1:matrix.org"); | ||
let event = |msg: &str| make_test_event(room_id, msg); | ||
|
||
let event_comte = event("comté"); | ||
let event_brigand = event("brigand du jorat"); | ||
let event_raclette = event("raclette"); | ||
let event_morbier = event("morbier"); | ||
let event_gruyere = event("gruyère"); | ||
let event_tome = event("tome"); | ||
let event_mont_dor = event("mont d'or"); | ||
|
||
self.handle_linked_chunk_updates( | ||
room_id, | ||
vec![ | ||
Update::NewItemsChunk { previous: None, new: CId::new(0), next: None }, | ||
Update::PushItems { | ||
at: Position::new(CId::new(0), 0), | ||
items: vec![event_comte.clone(), event_brigand.clone()], | ||
}, | ||
Update::NewGapChunk { | ||
previous: Some(CId::new(0)), | ||
new: CId::new(1), | ||
next: None, | ||
gap: Gap { prev_token: "brillat-savarin".to_owned() }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I WANT MORE 🧀 |
||
}, | ||
Update::NewItemsChunk { previous: Some(CId::new(1)), new: CId::new(2), next: None }, | ||
Update::PushItems { | ||
at: Position::new(CId::new(2), 0), | ||
items: vec![event_morbier.clone(), event_mont_dor.clone()], | ||
}, | ||
], | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
// Add other events in another room, to ensure filtering take the `room_id` into | ||
// account. | ||
self.handle_linked_chunk_updates( | ||
another_room_id, | ||
vec![ | ||
Update::NewItemsChunk { previous: None, new: CId::new(0), next: None }, | ||
Update::PushItems { | ||
at: Position::new(CId::new(0), 0), | ||
items: vec![event_tome.clone()], | ||
}, | ||
], | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
let duplicated_events = self | ||
.filter_duplicated_events( | ||
room_id, | ||
vec![ | ||
event_comte.event_id().unwrap().to_owned(), | ||
event_raclette.event_id().unwrap().to_owned(), | ||
event_morbier.event_id().unwrap().to_owned(), | ||
event_gruyere.event_id().unwrap().to_owned(), | ||
event_tome.event_id().unwrap().to_owned(), | ||
event_mont_dor.event_id().unwrap().to_owned(), | ||
], | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
assert_eq!(duplicated_events.len(), 3); | ||
assert_eq!(duplicated_events[0], event_comte.event_id().unwrap()); | ||
assert_eq!(duplicated_events[1], event_morbier.event_id().unwrap()); | ||
assert_eq!(duplicated_events[2], event_mont_dor.event_id().unwrap()); | ||
} | ||
} | ||
|
||
/// Macro building to allow your `EventCacheStore` implementation to run the | ||
|
@@ -584,6 +660,13 @@ macro_rules! event_cache_store_integration_tests { | |
get_event_cache_store().await.unwrap().into_event_cache_store(); | ||
event_cache_store.test_remove_room().await; | ||
} | ||
|
||
#[async_test] | ||
async fn test_filter_duplicated_events() { | ||
let event_cache_store = | ||
get_event_cache_store().await.unwrap().into_event_cache_store(); | ||
event_cache_store.test_filter_duplicated_events().await; | ||
} | ||
} | ||
}; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,7 @@ use matrix_sdk_common::{ | |
}; | ||
use ruma::{ | ||
time::{Instant, SystemTime}, | ||
MxcUri, OwnedMxcUri, RoomId, | ||
MxcUri, OwnedEventId, OwnedMxcUri, RoomId, | ||
}; | ||
|
||
use super::{ | ||
|
@@ -148,6 +148,35 @@ impl EventCacheStore for MemoryStore { | |
Ok(()) | ||
} | ||
|
||
async fn filter_duplicated_events( | ||
&self, | ||
room_id: &RoomId, | ||
mut events: Vec<OwnedEventId>, | ||
) -> Result<Vec<OwnedEventId>, Self::Error> { | ||
// Collect all duplicated events. | ||
let inner = self.inner.read().unwrap(); | ||
|
||
let mut duplicated_events = Vec::new(); | ||
|
||
for event in inner.events.unordered_events(room_id) { | ||
// If `events` is empty, we can short-circuit. | ||
if events.is_empty() { | ||
break; | ||
} | ||
Comment on lines
+162
to
+165
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No because we remove events one by one from |
||
|
||
if let Some(known_event_id) = event.event_id() { | ||
// This event exists in the store event! | ||
if let Some(position) = | ||
events.iter().position(|new_event_id| &known_event_id == new_event_id) | ||
{ | ||
duplicated_events.push(events.remove(position)); | ||
} | ||
} | ||
} | ||
|
||
Ok(duplicated_events) | ||
} | ||
|
||
async fn add_media_content( | ||
&self, | ||
request: &MediaRequestParameters, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️ 🧀