improvement: optimize state storage
This commit is contained in:
parent
44425a903a
commit
100307c936
9 changed files with 341 additions and 254 deletions
|
@ -106,7 +106,6 @@ pub async fn leave_room_route(
|
|||
ErrorKind::BadState,
|
||||
"Cannot leave a room you are not a member of.",
|
||||
))?
|
||||
.1
|
||||
.content,
|
||||
)
|
||||
.expect("from_value::<Raw<..>> can never fail")
|
||||
|
@ -195,7 +194,6 @@ pub async fn kick_user_route(
|
|||
ErrorKind::BadState,
|
||||
"Cannot kick member that's not in the room.",
|
||||
))?
|
||||
.1
|
||||
.content,
|
||||
)
|
||||
.expect("Raw::from_value always works")
|
||||
|
@ -251,7 +249,7 @@ pub async fn ban_user_route(
|
|||
is_direct: None,
|
||||
third_party_invite: None,
|
||||
}),
|
||||
|(_, event)| {
|
||||
|event| {
|
||||
let mut event =
|
||||
serde_json::from_value::<Raw<member::MemberEventContent>>(event.content)
|
||||
.expect("Raw::from_value always works")
|
||||
|
@ -302,7 +300,6 @@ pub async fn unban_user_route(
|
|||
ErrorKind::BadState,
|
||||
"Cannot unban a user who is not banned.",
|
||||
))?
|
||||
.1
|
||||
.content,
|
||||
)
|
||||
.expect("from_value::<Raw<..>> can never fail")
|
||||
|
@ -617,10 +614,7 @@ async fn join_room_by_id_helper(
|
|||
&db.globals,
|
||||
)?;
|
||||
}
|
||||
let mut long_id = room_id.as_bytes().to_vec();
|
||||
long_id.push(0xff);
|
||||
long_id.extend_from_slice(id.as_bytes());
|
||||
state.insert((pdu.kind.clone(), state_key.clone()), long_id);
|
||||
state.insert((pdu.kind.clone(), state_key.clone()), pdu.event_id.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -629,7 +623,7 @@ async fn join_room_by_id_helper(
|
|||
pdu.kind.clone(),
|
||||
pdu.state_key.clone().expect("join event has state key"),
|
||||
),
|
||||
pdu_id.clone(),
|
||||
pdu.event_id.clone(),
|
||||
);
|
||||
|
||||
db.rooms.force_state(room_id, state, &db.globals)?;
|
||||
|
|
|
@ -49,7 +49,6 @@ pub async fn set_displayname_route(
|
|||
"Tried to send displayname update for user not in the room.",
|
||||
)
|
||||
})?
|
||||
.1
|
||||
.content
|
||||
.clone(),
|
||||
)
|
||||
|
@ -144,7 +143,6 @@ pub async fn set_avatar_url_route(
|
|||
"Tried to send avatar url update for user not in the room.",
|
||||
)
|
||||
})?
|
||||
.1
|
||||
.content
|
||||
.clone(),
|
||||
)
|
||||
|
|
|
@ -380,7 +380,6 @@ pub async fn upgrade_room_route(
|
|||
db.rooms
|
||||
.room_state_get(&body.room_id, &EventType::RoomCreate, "")?
|
||||
.ok_or_else(|| Error::bad_database("Found room without m.room.create event."))?
|
||||
.1
|
||||
.content,
|
||||
)
|
||||
.expect("Raw::from_value always works")
|
||||
|
@ -452,7 +451,7 @@ pub async fn upgrade_room_route(
|
|||
// Replicate transferable state events to the new room
|
||||
for event_type in transferable_state_events {
|
||||
let event_content = match db.rooms.room_state_get(&body.room_id, &event_type, "")? {
|
||||
Some((_, v)) => v.content.clone(),
|
||||
Some(v) => v.content.clone(),
|
||||
None => continue, // Skipping missing events.
|
||||
};
|
||||
|
||||
|
@ -482,7 +481,6 @@ pub async fn upgrade_room_route(
|
|||
db.rooms
|
||||
.room_state_get(&body.room_id, &EventType::RoomPowerLevels, "")?
|
||||
.ok_or_else(|| Error::bad_database("Found room without m.room.create event."))?
|
||||
.1
|
||||
.content,
|
||||
)
|
||||
.expect("database contains invalid PDU")
|
||||
|
|
|
@ -112,7 +112,7 @@ pub async fn get_state_events_route(
|
|||
&& !matches!(
|
||||
db.rooms
|
||||
.room_state_get(&body.room_id, &EventType::RoomHistoryVisibility, "")?
|
||||
.map(|(_, event)| {
|
||||
.map(|event| {
|
||||
serde_json::from_value::<HistoryVisibilityEventContent>(event.content)
|
||||
.map_err(|_| {
|
||||
Error::bad_database(
|
||||
|
@ -159,7 +159,7 @@ pub async fn get_state_events_for_key_route(
|
|||
&& !matches!(
|
||||
db.rooms
|
||||
.room_state_get(&body.room_id, &EventType::RoomHistoryVisibility, "")?
|
||||
.map(|(_, event)| {
|
||||
.map(|event| {
|
||||
serde_json::from_value::<HistoryVisibilityEventContent>(event.content)
|
||||
.map_err(|_| {
|
||||
Error::bad_database(
|
||||
|
@ -183,8 +183,7 @@ pub async fn get_state_events_for_key_route(
|
|||
.ok_or(Error::BadRequest(
|
||||
ErrorKind::NotFound,
|
||||
"State event not found.",
|
||||
))?
|
||||
.1;
|
||||
))?;
|
||||
|
||||
Ok(get_state_events_for_key::Response {
|
||||
content: serde_json::value::to_raw_value(&event.content)
|
||||
|
@ -211,7 +210,7 @@ pub async fn get_state_events_for_empty_key_route(
|
|||
&& !matches!(
|
||||
db.rooms
|
||||
.room_state_get(&body.room_id, &EventType::RoomHistoryVisibility, "")?
|
||||
.map(|(_, event)| {
|
||||
.map(|event| {
|
||||
serde_json::from_value::<HistoryVisibilityEventContent>(event.content)
|
||||
.map_err(|_| {
|
||||
Error::bad_database(
|
||||
|
@ -235,8 +234,7 @@ pub async fn get_state_events_for_empty_key_route(
|
|||
.ok_or(Error::BadRequest(
|
||||
ErrorKind::NotFound,
|
||||
"State event not found.",
|
||||
))?
|
||||
.1;
|
||||
))?;
|
||||
|
||||
Ok(get_state_events_for_empty_key::Response {
|
||||
content: serde_json::value::to_raw_value(&event.content)
|
||||
|
|
|
@ -96,7 +96,7 @@ pub async fn sync_events_route(
|
|||
|
||||
// Database queries:
|
||||
|
||||
let current_state_hash = db.rooms.current_state_hash(&room_id)?;
|
||||
let current_shortstatehash = db.rooms.current_shortstatehash(&room_id)?;
|
||||
|
||||
// These type is Option<Option<_>>. The outer Option is None when there is no event between
|
||||
// since and the current room state, meaning there should be no updates.
|
||||
|
@ -109,9 +109,11 @@ pub async fn sync_events_route(
|
|||
.next()
|
||||
.is_some();
|
||||
|
||||
let since_state_hash = first_pdu_before_since
|
||||
.as_ref()
|
||||
.map(|pdu| db.rooms.pdu_state_hash(&pdu.as_ref().ok()?.0).ok()?);
|
||||
let since_shortstatehash = first_pdu_before_since.as_ref().map(|pdu| {
|
||||
db.rooms
|
||||
.pdu_shortstatehash(&pdu.as_ref().ok()?.1.event_id)
|
||||
.ok()?
|
||||
});
|
||||
|
||||
let (
|
||||
heroes,
|
||||
|
@ -119,7 +121,7 @@ pub async fn sync_events_route(
|
|||
invited_member_count,
|
||||
joined_since_last_sync,
|
||||
state_events,
|
||||
) = if pdus_after_since && Some(¤t_state_hash) != since_state_hash.as_ref() {
|
||||
) = if pdus_after_since && Some(current_shortstatehash) != since_shortstatehash {
|
||||
let current_state = db.rooms.room_state_full(&room_id)?;
|
||||
let current_members = current_state
|
||||
.iter()
|
||||
|
@ -129,11 +131,18 @@ pub async fn sync_events_route(
|
|||
let encrypted_room = current_state
|
||||
.get(&(EventType::RoomEncryption, "".to_owned()))
|
||||
.is_some();
|
||||
let since_state = since_state_hash.as_ref().map(|state_hash| {
|
||||
state_hash
|
||||
.as_ref()
|
||||
.and_then(|state_hash| db.rooms.state_full(&room_id, &state_hash).ok())
|
||||
});
|
||||
let since_state = since_shortstatehash
|
||||
.as_ref()
|
||||
.map(|since_shortstatehash| {
|
||||
Ok::<_, Error>(
|
||||
since_shortstatehash
|
||||
.map(|since_shortstatehash| {
|
||||
db.rooms.state_full(&room_id, since_shortstatehash)
|
||||
})
|
||||
.transpose()?,
|
||||
)
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let since_encryption = since_state.as_ref().map(|state| {
|
||||
state
|
||||
|
@ -496,16 +505,16 @@ pub async fn sync_events_route(
|
|||
.and_then(|pdu| pdu.ok())
|
||||
.and_then(|pdu| {
|
||||
db.rooms
|
||||
.pdu_state_hash(&pdu.0)
|
||||
.pdu_shortstatehash(&pdu.1.event_id)
|
||||
.ok()?
|
||||
.ok_or_else(|| Error::bad_database("Pdu in db doesn't have a state hash."))
|
||||
.ok()
|
||||
})
|
||||
.and_then(|state_hash| {
|
||||
.and_then(|shortstatehash| {
|
||||
db.rooms
|
||||
.state_get(
|
||||
&room_id,
|
||||
&state_hash,
|
||||
shortstatehash,
|
||||
&EventType::RoomMember,
|
||||
sender_user.as_str(),
|
||||
)
|
||||
|
@ -513,14 +522,14 @@ pub async fn sync_events_route(
|
|||
.ok_or_else(|| Error::bad_database("State hash in db doesn't have a state."))
|
||||
.ok()
|
||||
})
|
||||
.and_then(|(pdu_id, pdu)| {
|
||||
.and_then(|pdu| {
|
||||
serde_json::from_value::<Raw<ruma::events::room::member::MemberEventContent>>(
|
||||
pdu.content.clone(),
|
||||
)
|
||||
.expect("Raw::from_value always works")
|
||||
.deserialize()
|
||||
.map_err(|_| Error::bad_database("Invalid PDU in database."))
|
||||
.map(|content| (pdu_id, pdu, content))
|
||||
.map(|content| (pdu, content))
|
||||
.ok()
|
||||
}) {
|
||||
since_member
|
||||
|
@ -529,7 +538,7 @@ pub async fn sync_events_route(
|
|||
continue;
|
||||
};
|
||||
|
||||
let left_since_last_sync = since_member.2.membership == MembershipState::Join;
|
||||
let left_since_last_sync = since_member.1.membership == MembershipState::Join;
|
||||
|
||||
let left_room = if left_since_last_sync {
|
||||
device_list_left.extend(
|
||||
|
@ -550,10 +559,10 @@ pub async fn sync_events_route(
|
|||
let pdus = db.rooms.pdus_since(&sender_user, &room_id, since)?;
|
||||
let mut room_events = pdus
|
||||
.filter_map(|pdu| pdu.ok()) // Filter out buggy events
|
||||
.take_while(|(pdu_id, _)| since_member.0 != pdu_id)
|
||||
.take_while(|(pdu_id, pdu)| &since_member.0 != pdu)
|
||||
.map(|(_, pdu)| pdu.to_sync_room_event())
|
||||
.collect::<Vec<_>>();
|
||||
room_events.push(since_member.1.to_sync_room_event());
|
||||
room_events.push(since_member.0.to_sync_room_event());
|
||||
|
||||
sync_events::LeftRoom {
|
||||
account_data: sync_events::AccountData { events: Vec::new() },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue