diff --git a/include/ircd/m/room.h b/include/ircd/m/room.h index 477090360..fc1ea1846 100644 --- a/include/ircd/m/room.h +++ b/include/ircd/m/room.h @@ -73,9 +73,9 @@ namespace ircd::m /// struct ircd::m::room { + struct messages; struct state; struct members; - struct messages; struct origins; using id = m::id::room; @@ -90,9 +90,6 @@ struct ircd::m::room bool get(std::nothrow_t, const string_view &type, const string_view &state_key, const event::closure &) const; void get(const string_view &type, const string_view &state_key, const event::closure &) const; - // X - void for_each(const event::closure &) const; - // misc bool membership(const m::id::user &, const string_view &membership = "join") const; @@ -103,9 +100,35 @@ struct ircd::m::room {} }; +/// Interface to room messages +/// +/// This interface focuses on room messages (state and ephemeral) from all +/// integrated timelines. Most queries to this interface respond in linear +/// time. +/// +struct ircd::m::room::messages +{ + m::room room; + + void for_each(const event::id::closure &) const; + void for_each(const event::closure &) const; + + bool test(const event::id::closure_bool &view) const; + bool test(const event::closure_bool &view) const; + + messages(const m::room &room) + :room{room} + {} +}; + /// Interface to room state. /// -/// This interface focuses specifically on the details of room state. +/// This interface focuses specifically on the details of room state. Most of +/// the queries to this interface respond in logarithmic time. Note that all +/// iterations are over the state tree. If an event with a state_key is present +/// in room::messages but it is not present in room::state (state tree) it was +/// accepted into the room but we will not apply it to our machine, though +/// other parties may (this is a state-conflict). /// struct ircd::m::room::state { diff --git a/ircd/m/room.cc b/ircd/m/room.cc index 66439fe7f..15c29b17c 100644 --- a/ircd/m/room.cc +++ b/ircd/m/room.cc @@ -342,35 +342,6 @@ const return ret; } -void -ircd::m::room::for_each(const event::closure &closure) -const -{ - auto it - { - dbs::room_events.begin(room_id) - }; - - event::fetch event; - if(it) do - { - const auto &key{it->first}; - const auto part - { - dbs::room_events_key(key) - }; - - const auto event_id - { - std::get<1>(part) - }; - - if(seek(event, event_id, std::nothrow)) - closure(event); - } - while(++it); -} - void ircd::m::room::get(const string_view &type, const string_view &state_key, @@ -392,6 +363,81 @@ const return state.get(std::nothrow, type, state_key, closure); } +// +// room::messages +// + +void +ircd::m::room::messages::for_each(const event::closure &closure) +const +{ + event::fetch event; + for_each(event::id::closure{[&closure, &event] + (const event::id &event_id) + { + if(seek(event, event_id, std::nothrow)) + closure(event); + }}); +} + +void +ircd::m::room::messages::for_each(const event::id::closure &closure) +const +{ + test(event::id::closure_bool{[&closure] + (const event::id &event_id) + { + closure(event_id); + return false; + }}); +} + +bool +ircd::m::room::messages::test(const event::closure_bool &closure) +const +{ + event::fetch event; + return test(event::id::closure_bool{[&closure, &event] + (const m::event::id &event_id) + { + if(seek(event, event_id, std::nothrow)) + if(closure(event)) + return true; + + return false; + }}); +} + +bool +ircd::m::room::messages::test(const event::id::closure_bool &closure) +const +{ + auto it + { + dbs::room_events.begin(room.room_id) + }; + + if(it) do + { + const auto &key{it->first}; + const auto part + { + dbs::room_events_key(key) + }; + + const auto event_id + { + std::get<1>(part) + }; + + if(closure(event_id)) + return true; + } + while(++it); + + return false; +} + // // room::state //