Fix names and types misrepresenting PduCount as ShortEventId.

Add get_shorteventid_from_pdu_id() conversion.

Fix prev/next nearest-state interface (dev branch 642086ecfcfa).

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-09-29 09:44:45 +00:00
parent 368ead20a6
commit e6c85c97c6
16 changed files with 157 additions and 87 deletions

View File

@@ -17,7 +17,7 @@ use tuwunel_core::{
use tuwunel_database::{Interfix, Map};
use crate::rooms::{
short::{ShortEventId, ShortRoomId},
short::ShortRoomId,
timeline::{PduId, RawPduId},
};
@@ -52,12 +52,12 @@ impl Data {
&'a self,
user_id: &'a UserId,
shortroomid: ShortRoomId,
target: ShortEventId,
target: PduCount,
from: PduCount,
dir: Direction,
) -> impl Stream<Item = (PduCount, impl Event)> + Send + '_ {
let mut current = ArrayVec::<u8, 16>::new();
current.extend(target.to_be_bytes());
current.extend(target.into_unsigned().to_be_bytes());
current.extend(
from.saturating_inc(dir)
.into_unsigned()
@@ -75,12 +75,12 @@ impl Data {
.boxed(),
}
.ignore_err()
.ready_take_while(move |key| key.starts_with(&target.to_be_bytes()))
.ready_take_while(move |key| key.starts_with(&target.into_unsigned().to_be_bytes()))
.map(|to_from| u64_from_u8(&to_from[8..16]))
.map(PduCount::from_unsigned)
.map(move |shorteventid| (user_id, shortroomid, shorteventid))
.wide_filter_map(async |(user_id, shortroomid, shorteventid)| {
let pdu_id: RawPduId = PduId { shortroomid, shorteventid }.into();
.map(move |count| (user_id, shortroomid, count))
.wide_filter_map(async |(user_id, shortroomid, count)| {
let pdu_id: RawPduId = PduId { shortroomid, count }.into();
let mut pdu = self
.services
.timeline
@@ -95,7 +95,7 @@ impl Data {
.ok();
}
Some((shorteventid, pdu))
Some((count, pdu))
})
}

View File

@@ -64,7 +64,7 @@ impl Service {
let mut pdus: Vec<_> = self
.db
.get_relations(user_id, room_id, target, from, dir)
.get_relations(user_id, room_id, target.into(), from, dir)
.collect()
.await;
@@ -83,7 +83,7 @@ impl Service {
let relations: Vec<_> = self
.db
.get_relations(user_id, room_id, target, from, dir)
.get_relations(user_id, room_id, target.into(), from, dir)
.collect()
.await;

View File

@@ -63,7 +63,7 @@ impl Service {
room_id: &RoomId,
user_id: &UserId,
) -> Result<Raw<AnySyncEphemeralRoomEvent>> {
let pdu_count = self
let count = self
.private_read_get_count(room_id, user_id)
.map_err(|e| {
err!(Database(warn!("No private read receipt was set in {room_id}: {e}")))
@@ -79,9 +79,9 @@ impl Service {
)))
});
let (pdu_count, shortroomid) = try_join!(pdu_count, shortroomid)?;
let shorteventid = PduCount::Normal(pdu_count);
let pdu_id: RawPduId = PduId { shortroomid, shorteventid }.into();
let (count, shortroomid) = try_join!(count, shortroomid)?;
let count = PduCount::Normal(count);
let pdu_id: RawPduId = PduId { shortroomid, count }.into();
let pdu = self
.services
.timeline

View File

@@ -182,11 +182,7 @@ fn search_pdu_ids_query_word(
word: &str,
) -> impl Stream<Item = Val<'_>> + Send + '_ + use<'_> {
// rustc says const'ing this not yet stable
let end_id: RawPduId = PduId {
shortroomid,
shorteventid: PduCount::max(),
}
.into();
let end_id: RawPduId = PduId { shortroomid, count: PduCount::max() }.into();
// Newest pdus first
let end = make_tokenid(shortroomid, word, &end_id);

View File

@@ -3,7 +3,7 @@ use std::{borrow::Borrow, fmt::Debug, mem::size_of_val, sync::Arc};
use futures::{FutureExt, Stream, StreamExt};
use ruma::{EventId, OwnedRoomId, RoomId, events::StateEventType};
use serde::Deserialize;
pub use tuwunel_core::matrix::pdu::{ShortEventId, ShortId, ShortRoomId, ShortStateKey};
pub use tuwunel_core::matrix::{ShortEventId, ShortId, ShortRoomId, ShortStateKey};
use tuwunel_core::{
Err, Result, err, implement,
matrix::StateKey,

View File

@@ -128,7 +128,7 @@ impl Service {
&'a self,
user_id: &'a UserId,
room_id: &'a RoomId,
shorteventid: PduCount,
count: PduCount,
_inc: &'a IncludeThreads,
) -> impl Stream<Item = Result<(PduCount, PduEvent)>> + Send {
self.services
@@ -136,7 +136,7 @@ impl Service {
.get_shortroomid(room_id)
.map_ok(move |shortroomid| PduId {
shortroomid,
shorteventid: shorteventid.saturating_sub(1),
count: count.saturating_sub(1),
})
.map_ok(Into::into)
.map_ok(move |current: RawPduId| {
@@ -162,7 +162,7 @@ impl Service {
pdu.as_mut_pdu().remove_transaction_id().ok();
}
Some((pdu_id.shorteventid, pdu))
Some((pdu_id.count, pdu))
})
.map(Ok)
})

View File

@@ -178,7 +178,7 @@ where
.reset_notification_counts(pdu.sender(), pdu.room_id());
let count = PduCount::Normal(*next_count1);
let pdu_id: RawPduId = PduId { shortroomid, shorteventid: count }.into();
let pdu_id: RawPduId = PduId { shortroomid, count }.into();
// Insert pdu
self.append_pdu_json(&pdu_id, pdu, &pdu_json, count);

View File

@@ -198,7 +198,7 @@ pub async fn backfill_pdu(
let count: i64 = (*count).try_into()?;
let pdu_id: RawPduId = PduId {
shortroomid,
shorteventid: PduCount::Backfilled(validated!(0 - count)),
count: PduCount::Backfilled(validated!(0 - count)),
}
.into();

View File

@@ -23,7 +23,10 @@ use serde::Deserialize;
pub use tuwunel_core::matrix::pdu::{PduId, RawPduId};
use tuwunel_core::{
Err, Result, at, err, implement,
matrix::pdu::{PduCount, PduEvent},
matrix::{
ShortEventId,
pdu::{PduCount, PduEvent},
},
trace,
utils::{
MutexMap, MutexMapGuard,
@@ -167,7 +170,7 @@ pub async fn latest_item_in_room(
}
/// Returns the shortstatehash of the room at the event directly preceding the
/// exclusive `before` param. `before` does not have to be a valid shorteventid
/// exclusive `before` param. `before` does not have to be a valid count
/// or in the room.
#[implement(Service)]
#[tracing::instrument(skip(self), level = "debug")]
@@ -176,16 +179,30 @@ pub async fn prev_shortstatehash(
room_id: &RoomId,
before: PduCount,
) -> Result<ShortStateHash> {
let prev = self.prev_timeline_count(room_id, before).await?;
let shortroomid: ShortRoomId = self
.services
.short
.get_shortroomid(room_id)
.await
.map_err(|e| err!(Request(NotFound("Room {room_id:?} not found: {e:?}"))))?;
let before = PduId { shortroomid, count: before };
let prev = PduId {
shortroomid,
count: self.prev_timeline_count(&before).await?,
};
let shorteventid = self.get_shorteventid_from_pdu_id(&prev).await?;
self.services
.state
.get_shortstatehash(prev.into_unsigned())
.get_shortstatehash(shorteventid)
.await
}
/// Returns the shortstatehash of the room at the event directly following the
/// exclusive `after` param. `after` does not have to be a valid shorteventid or
/// exclusive `after` param. `after` does not have to be a valid count or
/// in the room.
#[implement(Service)]
#[tracing::instrument(skip(self), level = "debug")]
@@ -194,11 +211,71 @@ pub async fn next_shortstatehash(
room_id: &RoomId,
after: PduCount,
) -> Result<ShortStateHash> {
let next = self.next_timeline_count(room_id, after).await?;
let shortroomid: ShortRoomId = self
.services
.short
.get_shortroomid(room_id)
.await
.map_err(|e| err!(Request(NotFound("Room {room_id:?} not found: {e:?}"))))?;
let after = PduId { shortroomid, count: after };
let next = PduId {
shortroomid,
count: self.next_timeline_count(&after).await?,
};
let shorteventid = self.get_shorteventid_from_pdu_id(&next).await?;
self.services
.state
.get_shortstatehash(next.into_unsigned())
.get_shortstatehash(shorteventid)
.await
}
/// Returns the shortstatehash of the room at the event
#[implement(Service)]
#[tracing::instrument(skip(self), level = "debug")]
pub async fn get_shortstatehash(
&self,
room_id: &RoomId,
count: PduCount,
) -> Result<ShortStateHash> {
let shortroomid: ShortRoomId = self
.services
.short
.get_shortroomid(room_id)
.await
.map_err(|e| err!(Request(NotFound("Room {room_id:?} not found: {e:?}"))))?;
let pdu_id = PduId { shortroomid, count };
let shorteventid = self.get_shorteventid_from_pdu_id(&pdu_id).await?;
self.services
.state
.get_shortstatehash(shorteventid)
.await
}
/// Returns the `shorteventid` from the `pdu_id`
#[implement(Service)]
pub async fn get_shorteventid_from_pdu_id(&self, pdu_id: &PduId) -> Result<ShortEventId> {
let event_id = self.get_event_id_from_pdu_id(pdu_id).await?;
self.services
.short
.get_shorteventid(&event_id)
.await
}
/// Returns the `event_id` from the `pdu_id`
#[implement(Service)]
pub async fn get_event_id_from_pdu_id(&self, pdu_id: &PduId) -> Result<OwnedEventId> {
let pdu_id: RawPduId = (*pdu_id).into();
self.get_pdu_from_id(&pdu_id)
.map_ok(|pdu| pdu.event_id)
.await
}
@@ -206,10 +283,8 @@ pub async fn next_shortstatehash(
/// `before` does not have to be a valid shorteventid or in the room.
#[implement(Service)]
#[tracing::instrument(skip(self), level = "debug")]
pub async fn prev_timeline_count(&self, room_id: &RoomId, before: PduCount) -> Result<PduCount> {
let before = self
.count_to_id(room_id, before, Direction::Backward)
.await?;
pub async fn prev_timeline_count(&self, before: &PduId) -> Result<PduCount> {
let before = Self::pdu_count_to_id(before.shortroomid, before.count, Direction::Backward);
let pdu_ids = self
.db
@@ -230,10 +305,8 @@ pub async fn prev_timeline_count(&self, room_id: &RoomId, before: PduCount) -> R
/// `after` does not have to be a valid shorteventid or in the room.
#[implement(Service)]
#[tracing::instrument(skip(self), level = "debug")]
pub async fn next_timeline_count(&self, room_id: &RoomId, after: PduCount) -> Result<PduCount> {
let after = self
.count_to_id(room_id, after, Direction::Forward)
.await?;
pub async fn next_timeline_count(&self, after: &PduId) -> Result<PduCount> {
let after = Self::pdu_count_to_id(after.shortroomid, after.count, Direction::Forward);
let pdu_ids = self
.db
@@ -350,7 +423,7 @@ fn each_pdu((pdu_id, pdu): KeyVal<'_>, user_id: Option<&UserId>) -> Result<PdusI
async fn count_to_id(
&self,
room_id: &RoomId,
shorteventid: PduCount,
count: PduCount,
dir: Direction,
) -> Result<RawPduId> {
let shortroomid: ShortRoomId = self
@@ -360,13 +433,18 @@ async fn count_to_id(
.await
.map_err(|e| err!(Request(NotFound("Room {room_id:?} not found: {e:?}"))))?;
Ok(Self::pdu_count_to_id(shortroomid, count, dir))
}
#[implement(Service)]
fn pdu_count_to_id(shortroomid: ShortRoomId, count: PduCount, dir: Direction) -> RawPduId {
// +1 so we don't send the base event
let pdu_id = PduId {
shortroomid,
shorteventid: shorteventid.saturating_inc(dir),
count: count.saturating_inc(dir),
};
Ok(pdu_id.into())
pdu_id.into()
}
/// Returns the pdu.
@@ -486,7 +564,7 @@ pub async fn outlier_pdu_exists(&self, event_id: &EventId) -> Result {
pub async fn get_pdu_count(&self, event_id: &EventId) -> Result<PduCount> {
self.get_pdu_id(event_id)
.await
.map(|pdu_id| pdu_id.pdu_count())
.map(RawPduId::pdu_count)
}
/// Returns the pdu's id.