Skip to content
Snippets Groups Projects
pdu_metadata.rs 2.98 KiB
Newer Older
  • Learn to ignore specific revisions
  • use std::{mem, sync::Arc};
    
    use ruma::{EventId, RoomId, UserId};
    
    use crate::{
        database::KeyValueDatabase,
        service::{self, rooms::timeline::PduCount},
        services, utils, Error, PduEvent, Result,
    };
    
    Timo Kösters's avatar
    Timo Kösters committed
    impl service::rooms::pdu_metadata::Data for KeyValueDatabase {
    
        fn add_relation(&self, from: u64, to: u64) -> Result<()> {
    
            let mut key = to.to_be_bytes().to_vec();
            key.extend_from_slice(&from.to_be_bytes());
            self.tofrom_relation.insert(&key, &[])?;
    
        fn relations_until<'a>(
            &'a self,
            user_id: &'a UserId,
            shortroomid: u64,
            target: u64,
            until: PduCount,
        ) -> Result<Box<dyn Iterator<Item = Result<(PduCount, PduEvent)>> + 'a>> {
            let prefix = target.to_be_bytes().to_vec();
            let mut current = prefix.clone();
    
            let count_raw = match until {
                PduCount::Normal(x) => x - 1,
                PduCount::Backfilled(x) => {
                    current.extend_from_slice(&0_u64.to_be_bytes());
                    u64::MAX - x - 1
                }
            };
            current.extend_from_slice(&count_raw.to_be_bytes());
    
            Ok(Box::new(
                self.tofrom_relation
                    .iter_from(&current, true)
                    .take_while(move |(k, _)| k.starts_with(&prefix))
                    .map(move |(tofrom, _data)| {
                        let from = utils::u64_from_bytes(&tofrom[(mem::size_of::<u64>())..])
                            .map_err(|_| Error::bad_database("Invalid count in tofrom_relation."))?;
    
                        let mut pduid = shortroomid.to_be_bytes().to_vec();
                        pduid.extend_from_slice(&from.to_be_bytes());
    
                        let mut pdu = services()
                            .rooms
                            .timeline
                            .get_pdu_from_id(&pduid)?
                            .ok_or_else(|| Error::bad_database("Pdu in tofrom_relation is invalid."))?;
                        if pdu.sender != user_id {
                            pdu.remove_transaction_id()?;
                        }
                        Ok((PduCount::Normal(from), pdu))
                    }),
            ))
        }
    
    
        fn mark_as_referenced(&self, room_id: &RoomId, event_ids: &[Arc<EventId>]) -> Result<()> {
    
            for prev in event_ids {
                let mut key = room_id.as_bytes().to_vec();
                key.extend_from_slice(prev.as_bytes());
                self.referencedevents.insert(&key, &[])?;
            }
    
            Ok(())
        }
    
    
        fn is_event_referenced(&self, room_id: &RoomId, event_id: &EventId) -> Result<bool> {
    
    Timo Kösters's avatar
    Timo Kösters committed
            let mut key = room_id.as_bytes().to_vec();
            key.extend_from_slice(event_id.as_bytes());
    
            Ok(self.referencedevents.get(&key)?.is_some())
    
        fn mark_event_soft_failed(&self, event_id: &EventId) -> Result<()> {
    
            self.softfailedeventids.insert(event_id.as_bytes(), &[])
    
        fn is_event_soft_failed(&self, event_id: &EventId) -> Result<bool> {
    
            self.softfailedeventids
    
                .get(event_id.as_bytes())
    
                .map(|o| o.is_some())