mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-18 21:52:30 -04:00
feat(base): Rename recency_timestamp to recency_stamp.
This patch renames “recency timestamp” to “recency stamp”. It prepares the fact that simplified sliding sync has a `bump_stamp` instead of a `timestamp`. The notion of _timestamp_ must be removed.
This commit is contained in:
@@ -91,8 +91,8 @@ bitflags! {
|
||||
/// The reason why a [`RoomInfoNotableUpdate`] is emitted.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct RoomInfoNotableUpdateReasons: u8 {
|
||||
/// The recency timestamp of the `Room` has changed.
|
||||
const RECENCY_TIMESTAMP = 0b0000_0001;
|
||||
/// The recency stamp of the `Room` has changed.
|
||||
const RECENCY_STAMP = 0b0000_0001;
|
||||
|
||||
/// The latest event of the `Room` has changed.
|
||||
const LATEST_EVENT = 0b0000_0010;
|
||||
@@ -940,12 +940,12 @@ impl Room {
|
||||
self.inner.read().base_info.is_marked_unread
|
||||
}
|
||||
|
||||
/// Returns the recency timestamp of the room.
|
||||
/// Returns the recency stamp of the room.
|
||||
///
|
||||
/// Please read `RoomInfo::recency_timestamp` to learn more.
|
||||
/// Please read `RoomInfo::recency_stamp` to learn more.
|
||||
#[cfg(feature = "experimental-sliding-sync")]
|
||||
pub fn recency_timestamp(&self) -> Option<MilliSecondsSinceUnixEpoch> {
|
||||
self.inner.read().recency_timestamp
|
||||
pub fn recency_stamp(&self) -> Option<u64> {
|
||||
self.inner.read().recency_stamp
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,15 +1006,15 @@ pub struct RoomInfo {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) cached_display_name: Option<DisplayName>,
|
||||
|
||||
/// The recency timestamp of this room.
|
||||
/// The recency stamp of this room.
|
||||
///
|
||||
/// It's not to be confused with `origin_server_ts` of the latest event.
|
||||
/// Sliding Sync might "ignore” some events when computing the recency
|
||||
/// timestamp of the room. Thus, using this `recency_timestamp` value is
|
||||
/// stamp of the room. Thus, using this `recency_stamp` value is
|
||||
/// more accurate than relying on the latest event.
|
||||
#[cfg(feature = "experimental-sliding-sync")]
|
||||
#[serde(default)]
|
||||
pub(crate) recency_timestamp: Option<MilliSecondsSinceUnixEpoch>,
|
||||
pub(crate) recency_stamp: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
@@ -1053,7 +1053,7 @@ impl RoomInfo {
|
||||
warned_about_unknown_room_version: Arc::new(false.into()),
|
||||
cached_display_name: None,
|
||||
#[cfg(feature = "experimental-sliding-sync")]
|
||||
recency_timestamp: None,
|
||||
recency_stamp: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1459,12 +1459,12 @@ impl RoomInfo {
|
||||
self.latest_event.as_deref()
|
||||
}
|
||||
|
||||
/// Updates the recency timestamp of this room.
|
||||
/// Updates the recency stamp of this room.
|
||||
///
|
||||
/// Please read [`Self::recency_timestamp`] to learn more.
|
||||
/// Please read [`Self::recency_stamp`] to learn more.
|
||||
#[cfg(feature = "experimental-sliding-sync")]
|
||||
pub(crate) fn update_recency_timestamp(&mut self, timestamp: MilliSecondsSinceUnixEpoch) {
|
||||
self.recency_timestamp = Some(timestamp);
|
||||
pub(crate) fn update_recency_stamp(&mut self, stamp: u64) {
|
||||
self.recency_stamp = Some(stamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1675,7 +1675,7 @@ mod tests {
|
||||
read_receipts: Default::default(),
|
||||
warned_about_unknown_room_version: Arc::new(false.into()),
|
||||
cached_display_name: None,
|
||||
recency_timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())),
|
||||
recency_stamp: Some(42),
|
||||
};
|
||||
|
||||
let info_json = json!({
|
||||
@@ -1728,7 +1728,7 @@ mod tests {
|
||||
"latest_active": null,
|
||||
"pending": []
|
||||
},
|
||||
"recency_timestamp": 42,
|
||||
"recency_stamp": 42,
|
||||
});
|
||||
|
||||
assert_eq!(serde_json::to_value(info).unwrap(), info_json);
|
||||
|
||||
@@ -29,7 +29,7 @@ use ruma::{
|
||||
},
|
||||
events::{AnyRoomAccountDataEvent, AnySyncStateEvent, AnySyncTimelineEvent},
|
||||
serde::Raw,
|
||||
JsOption, OwnedRoomId, RoomId,
|
||||
JsOption, MilliSecondsSinceUnixEpoch, OwnedRoomId, RoomId,
|
||||
};
|
||||
use tracing::{instrument, trace, warn};
|
||||
|
||||
@@ -768,18 +768,20 @@ fn process_room_properties(
|
||||
room_info.mark_members_missing();
|
||||
}
|
||||
|
||||
if let Some(recency_timestamp) = &room_data.timestamp {
|
||||
if room_info.recency_timestamp.as_ref() != Some(recency_timestamp) {
|
||||
room_info.update_recency_timestamp(*recency_timestamp);
|
||||
if let Some(MilliSecondsSinceUnixEpoch(recency_stamp)) = &room_data.timestamp {
|
||||
let recency_stamp: u64 = (*recency_stamp).into();
|
||||
|
||||
// If it's not a new room, let's emit a `RECENCY_TIMESTAMP` update.
|
||||
if room_info.recency_stamp != Some(recency_stamp) {
|
||||
room_info.update_recency_stamp(recency_stamp);
|
||||
|
||||
// If it's not a new room, let's emit a `RECENCY_STAMP` update.
|
||||
// For a new room, the room will appear as new, so we don't care about this
|
||||
// update.
|
||||
if !is_new_room {
|
||||
room_info_notable_updates
|
||||
.entry(room_id.to_owned())
|
||||
.or_default()
|
||||
.insert(RoomInfoNotableUpdateReasons::RECENCY_TIMESTAMP);
|
||||
.insert(RoomInfoNotableUpdateReasons::RECENCY_STAMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -812,8 +814,7 @@ mod tests {
|
||||
},
|
||||
mxc_uri, owned_mxc_uri, owned_user_id, room_alias_id, room_id,
|
||||
serde::Raw,
|
||||
uint, user_id, JsOption, MilliSecondsSinceUnixEpoch, MxcUri, OwnedRoomId, OwnedUserId,
|
||||
RoomAliasId, RoomId, UserId,
|
||||
uint, user_id, JsOption, MxcUri, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, UserId,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
@@ -1790,59 +1791,53 @@ mod tests {
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_recency_timestamp_is_found_when_processing_sliding_sync_response() {
|
||||
async fn test_recency_stamp_is_found_when_processing_sliding_sync_response() {
|
||||
// Given a logged-in client
|
||||
let client = logged_in_base_client(None).await;
|
||||
let room_id = room_id!("!r:e.uk");
|
||||
|
||||
// When I send sliding sync response containing a room with a recency timestamp
|
||||
// When I send sliding sync response containing a room with a recency stamp
|
||||
let room = assign!(v4::SlidingSyncRoom::new(), {
|
||||
timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())),
|
||||
});
|
||||
let response = response_with_room(room_id, room);
|
||||
client.process_sliding_sync(&response, &()).await.expect("Failed to process sync");
|
||||
|
||||
// Then the room in the client has the recency timestamp
|
||||
// Then the room in the client has the recency stamp
|
||||
let client_room = client.get_room(room_id).expect("No room found");
|
||||
assert_eq!(client_room.recency_timestamp().expect("No recency timestamp").0, 42u32.into());
|
||||
assert_eq!(client_room.recency_stamp().expect("No recency stamp"), 42);
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_recency_timestamp_can_be_overwritten_when_present_in_a_sliding_sync_response() {
|
||||
async fn test_recency_stamp_can_be_overwritten_when_present_in_a_sliding_sync_response() {
|
||||
// Given a logged-in client
|
||||
let client = logged_in_base_client(None).await;
|
||||
let room_id = room_id!("!r:e.uk");
|
||||
|
||||
{
|
||||
// When I send sliding sync response containing a room with a recency timestamp
|
||||
// When I send sliding sync response containing a room with a recency stamp
|
||||
let room = assign!(v4::SlidingSyncRoom::new(), {
|
||||
timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())),
|
||||
});
|
||||
let response = response_with_room(room_id, room);
|
||||
client.process_sliding_sync(&response, &()).await.expect("Failed to process sync");
|
||||
|
||||
// Then the room in the client has the recency timestamp
|
||||
// Then the room in the client has the recency stamp
|
||||
let client_room = client.get_room(room_id).expect("No room found");
|
||||
assert_eq!(
|
||||
client_room.recency_timestamp().expect("No recency timestamp").0,
|
||||
42u32.into()
|
||||
);
|
||||
assert_eq!(client_room.recency_stamp().expect("No recency stamp"), 42);
|
||||
}
|
||||
|
||||
{
|
||||
// When I send sliding sync response containing a room with NO recency timestamp
|
||||
// When I send sliding sync response containing a room with NO recency stamp
|
||||
let room = assign!(v4::SlidingSyncRoom::new(), {
|
||||
timestamp: None,
|
||||
});
|
||||
let response = response_with_room(room_id, room);
|
||||
client.process_sliding_sync(&response, &()).await.expect("Failed to process sync");
|
||||
|
||||
// Then the room in the client has the previous recency timestamp
|
||||
// Then the room in the client has the previous recency stamp
|
||||
let client_room = client.get_room(room_id).expect("No room found");
|
||||
assert_eq!(
|
||||
client_room.recency_timestamp().expect("No recency timestamp").0,
|
||||
42u32.into()
|
||||
);
|
||||
assert_eq!(client_room.recency_stamp().expect("No recency stamp"), 42);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1854,23 +1849,20 @@ mod tests {
|
||||
let response = response_with_room(room_id, room);
|
||||
client.process_sliding_sync(&response, &()).await.expect("Failed to process sync");
|
||||
|
||||
// Then the room in the client has the recency timestamp
|
||||
// Then the room in the client has the recency stamp
|
||||
let client_room = client.get_room(room_id).expect("No room found");
|
||||
assert_eq!(
|
||||
client_room.recency_timestamp().expect("No recency timestamp").0,
|
||||
153u32.into()
|
||||
);
|
||||
assert_eq!(client_room.recency_stamp().expect("No recency stamp"), 153);
|
||||
}
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_recency_timestamp_can_trigger_a_notable_update_reason() {
|
||||
async fn test_recency_stamp_can_trigger_a_notable_update_reason() {
|
||||
// Given a logged-in client
|
||||
let client = logged_in_base_client(None).await;
|
||||
let mut room_info_notable_update_stream = client.room_info_notable_update_receiver();
|
||||
let room_id = room_id!("!r:e.uk");
|
||||
|
||||
// When I send sliding sync response containing a room with a recency timestamp.
|
||||
// When I send sliding sync response containing a room with a recency stamp.
|
||||
let room = assign!(v4::SlidingSyncRoom::new(), {
|
||||
timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())),
|
||||
});
|
||||
@@ -1883,11 +1875,11 @@ mod tests {
|
||||
room_info_notable_update_stream.recv().await,
|
||||
Ok(RoomInfoNotableUpdate { room_id: received_room_id, reasons: received_reasons }) => {
|
||||
assert_eq!(received_room_id, room_id);
|
||||
assert!(!received_reasons.contains(RoomInfoNotableUpdateReasons::RECENCY_TIMESTAMP));
|
||||
assert!(!received_reasons.contains(RoomInfoNotableUpdateReasons::RECENCY_STAMP));
|
||||
}
|
||||
);
|
||||
|
||||
// When I send sliding sync response containing a room with a recency timestamp.
|
||||
// When I send sliding sync response containing a room with a recency stamp.
|
||||
let room = assign!(v4::SlidingSyncRoom::new(), {
|
||||
timestamp: Some(MilliSecondsSinceUnixEpoch(43u32.into())),
|
||||
});
|
||||
@@ -1899,7 +1891,7 @@ mod tests {
|
||||
room_info_notable_update_stream.recv().await,
|
||||
Ok(RoomInfoNotableUpdate { room_id: received_room_id, reasons: received_reasons }) => {
|
||||
assert_eq!(received_room_id, room_id);
|
||||
assert!(received_reasons.contains(RoomInfoNotableUpdateReasons::RECENCY_TIMESTAMP));
|
||||
assert!(received_reasons.contains(RoomInfoNotableUpdateReasons::RECENCY_STAMP));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ impl RoomInfoV1 {
|
||||
warned_about_unknown_room_version: Arc::new(false.into()),
|
||||
cached_display_name: None,
|
||||
#[cfg(feature = "experimental-sliding-sync")]
|
||||
recency_timestamp: None,
|
||||
recency_stamp: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ fn merge_stream_and_receiver(
|
||||
|
||||
// We are interested by these _reasons_.
|
||||
if reasons.contains(NotableUpdate::LATEST_EVENT) ||
|
||||
reasons.contains(NotableUpdate::RECENCY_TIMESTAMP) ||
|
||||
reasons.contains(NotableUpdate::RECENCY_STAMP) ||
|
||||
reasons.contains(NotableUpdate::READ_RECEIPT) ||
|
||||
reasons.contains(NotableUpdate::UNREAD_MARKER) {
|
||||
// Emit a `VectorDiff::Set` for the specific rooms.
|
||||
|
||||
@@ -14,20 +14,18 @@
|
||||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use ruma::MilliSecondsSinceUnixEpoch;
|
||||
|
||||
use super::{Room, Sorter};
|
||||
|
||||
struct RecencyMatcher<F>
|
||||
where
|
||||
F: Fn(&Room, &Room) -> (Option<MilliSecondsSinceUnixEpoch>, Option<MilliSecondsSinceUnixEpoch>),
|
||||
F: Fn(&Room, &Room) -> (Option<u64>, Option<u64>),
|
||||
{
|
||||
timestamps: F,
|
||||
recency_stamps: F,
|
||||
}
|
||||
|
||||
impl<F> RecencyMatcher<F>
|
||||
where
|
||||
F: Fn(&Room, &Room) -> (Option<MilliSecondsSinceUnixEpoch>, Option<MilliSecondsSinceUnixEpoch>),
|
||||
F: Fn(&Room, &Room) -> (Option<u64>, Option<u64>),
|
||||
{
|
||||
fn matches(&self, left: &Room, right: &Room) -> Ordering {
|
||||
if left.id() == right.id() {
|
||||
@@ -51,7 +49,7 @@ where
|
||||
return Ordering::Greater;
|
||||
}
|
||||
|
||||
match (self.timestamps)(left, right) {
|
||||
match (self.recency_stamps)(left, right) {
|
||||
(Some(left_timestamp), Some(right_timestamp)) => {
|
||||
left_timestamp.cmp(&right_timestamp).reverse()
|
||||
}
|
||||
@@ -66,11 +64,11 @@ where
|
||||
}
|
||||
|
||||
/// Create a new sorter that will sort two [`Room`] by recency, i.e. by
|
||||
/// comparing their [`matrix_sdk_base::RoomInfo::recency_timestamp`] value. The
|
||||
/// `Room` with the newest recency timestamp comes first, i.e. newest < oldest.
|
||||
/// comparing their [`matrix_sdk_base::RoomInfo::recency_stamp`] value. The
|
||||
/// `Room` with the newest recency stamp comes first, i.e. newest < oldest.
|
||||
pub fn new_sorter() -> impl Sorter {
|
||||
let matcher = RecencyMatcher {
|
||||
timestamps: move |left, right| (left.recency_timestamp(), right.recency_timestamp()),
|
||||
recency_stamps: move |left, right| (left.recency_stamp(), right.recency_stamp()),
|
||||
};
|
||||
|
||||
move |left, right| -> Ordering { matcher.matches(left, right) }
|
||||
@@ -79,85 +77,76 @@ pub fn new_sorter() -> impl Sorter {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use matrix_sdk_test::async_test;
|
||||
use ruma::{room_id, MilliSecondsSinceUnixEpoch, UInt};
|
||||
use ruma::room_id;
|
||||
|
||||
use super::{
|
||||
super::super::filters::{client_and_server_prelude, new_rooms},
|
||||
*,
|
||||
};
|
||||
|
||||
macro_rules! ms {
|
||||
($value:literal) => {
|
||||
MilliSecondsSinceUnixEpoch(UInt::new_wrapping($value))
|
||||
};
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_with_two_recency_timestamps() {
|
||||
async fn test_with_two_recency_stamps() {
|
||||
let (client, server, sliding_sync) = client_and_server_prelude().await;
|
||||
let [room_a, room_b] =
|
||||
new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync)
|
||||
.await;
|
||||
|
||||
// `room_a` has an older recency timestamp than `room_b`.
|
||||
// `room_a` has an older recency stamp than `room_b`.
|
||||
{
|
||||
let matcher =
|
||||
RecencyMatcher { timestamps: |_left, _right| (Some(ms!(1)), Some(ms!(2))) };
|
||||
let matcher = RecencyMatcher { recency_stamps: |_left, _right| (Some(1), Some(2)) };
|
||||
|
||||
// `room_a` is greater than `room_b`, i.e. it must come after `room_b`.
|
||||
assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Greater);
|
||||
}
|
||||
|
||||
// `room_b` has an older recency timestamp than `room_a`.
|
||||
// `room_b` has an older recency stamp than `room_a`.
|
||||
{
|
||||
let matcher =
|
||||
RecencyMatcher { timestamps: |_left, _right| (Some(ms!(2)), Some(ms!(1))) };
|
||||
let matcher = RecencyMatcher { recency_stamps: |_left, _right| (Some(2), Some(1)) };
|
||||
|
||||
// `room_a` is less than `room_b`, i.e. it must come before `room_b`.
|
||||
assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Less);
|
||||
}
|
||||
|
||||
// `room_a` has an equally old recency timestamp than `room_b`.
|
||||
// `room_a` has an equally old recency stamp than `room_b`.
|
||||
{
|
||||
let matcher =
|
||||
RecencyMatcher { timestamps: |_left, _right| (Some(ms!(1)), Some(ms!(1))) };
|
||||
let matcher = RecencyMatcher { recency_stamps: |_left, _right| (Some(1), Some(1)) };
|
||||
|
||||
assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Equal);
|
||||
}
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_with_one_recency_timestamp() {
|
||||
async fn test_with_one_recency_stamp() {
|
||||
let (client, server, sliding_sync) = client_and_server_prelude().await;
|
||||
let [room_a, room_b] =
|
||||
new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync)
|
||||
.await;
|
||||
|
||||
// `room_a` has a recency timestamp, `room_b` has no recency timestamp.
|
||||
// `room_a` has a recency stamp, `room_b` has no recency stamp.
|
||||
{
|
||||
let matcher = RecencyMatcher { timestamps: |_left, _right| (Some(ms!(1)), None) };
|
||||
let matcher = RecencyMatcher { recency_stamps: |_left, _right| (Some(1), None) };
|
||||
|
||||
assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Less);
|
||||
}
|
||||
|
||||
// `room_a` has no recency timestamp, `room_b` has a recency timestamp.
|
||||
// `room_a` has no recency stamp, `room_b` has a recency stamp.
|
||||
{
|
||||
let matcher = RecencyMatcher { timestamps: |_left, _right| (None, Some(ms!(1))) };
|
||||
let matcher = RecencyMatcher { recency_stamps: |_left, _right| (None, Some(1)) };
|
||||
|
||||
assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Greater);
|
||||
}
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_with_zero_recency_timestamp() {
|
||||
async fn test_with_zero_recency_stamp() {
|
||||
let (client, server, sliding_sync) = client_and_server_prelude().await;
|
||||
let [room_a, room_b] =
|
||||
new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync)
|
||||
.await;
|
||||
|
||||
// `room_a` and `room_b` has no recency timestamp.
|
||||
// `room_a` and `room_b` has no recency stamp.
|
||||
{
|
||||
let matcher = RecencyMatcher { timestamps: |_left, _right| (None, None) };
|
||||
let matcher = RecencyMatcher { recency_stamps: |_left, _right| (None, None) };
|
||||
|
||||
assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Equal);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user