0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 10:12:39 +01:00

ircd:Ⓜ️ Add meta column for sequential presently joined origins iteration.

This commit is contained in:
Jason Volk 2018-03-02 22:03:06 -08:00
parent 2be4d22403
commit a99fff0988
4 changed files with 184 additions and 37 deletions

View file

@ -14,6 +14,7 @@
namespace ircd::m::dbs
{
struct init;
struct write_opts;
// Database instance
extern std::shared_ptr<db::database> events;
@ -25,8 +26,10 @@ namespace ircd::m::dbs
// Event metadata columns
extern db::column state_node;
extern db::index room_events;
extern db::index room_origins;
// Lowlevel util
string_view room_origins_key(const mutable_buffer &out, const id::room &, const string_view &origin);
string_view room_events_key(const mutable_buffer &out, const id::room &, const uint64_t &depth, const id::event &);
string_view room_events_key(const mutable_buffer &out, const id::room &, const uint64_t &depth);
std::tuple<uint64_t, string_view> room_events_key(const string_view &amalgam);
@ -41,9 +44,16 @@ namespace ircd::m::dbs
bool exists(const event::id &);
// [SET (txn)] Basic write suite
string_view write(db::txn &, const mutable_buffer &rootout, const string_view &rootin, const event &);
string_view write(db::txn &, const event &, const write_opts &);
}
struct ircd::m::dbs::write_opts
{
string_view root_in;
mutable_buffer root_out;
bool present {true};
};
namespace ircd::m::dbs::desc
{
// Full description
@ -72,6 +82,8 @@ namespace ircd::m::dbs::desc
extern const db::prefix_transform events__room_events__pfx;
extern const db::comparator events__room_events__cmp;
extern const database::descriptor events__room_events;
extern const db::prefix_transform events__room_origins__pfx;
extern const database::descriptor events__room_origins;
}
struct ircd::m::dbs::init

View file

@ -33,6 +33,11 @@ decltype(ircd::m::dbs::room_events)
ircd::m::dbs::room_events
{};
/// Linkage for a reference to the room_origins column
decltype(ircd::m::dbs::room_origins)
ircd::m::dbs::room_origins
{};
//
// init
//
@ -58,6 +63,7 @@ ircd::m::dbs::init::init()
// Cache the columns for the metadata
state_node = db::column{*events, "_state_node"};
room_events = db::index{*events, "_room_events"};
room_origins = db::index{*events, "_room_origins"};
}
/// Shuts down the m::dbs subsystem; closes the events database. The extern
@ -68,6 +74,7 @@ noexcept
// Columns should be unrefed before DB closes
state_node = {};
room_events = {};
room_origins = {};
for(auto &column : event_column)
column = {};
@ -77,17 +84,17 @@ noexcept
namespace ircd::m::dbs
{
static void _index__room_events(db::txn &, const string_view &state_root, const event &);
static string_view _index_state(db::txn &, const mutable_buffer &root_out, const string_view &state_root, const event &);
static string_view _index_redact(db::txn &, const mutable_buffer &root_out, const string_view &state_root, const event &);
static string_view _index_ephem(db::txn &, const string_view &state_root, const event &);
static void _index__room_events(db::txn &, const event &, const write_opts &, const string_view &);
static void _index__room_origins(db::txn &, const event &, const write_opts &);
static string_view _index_state(db::txn &, const event &, const write_opts &);
static string_view _index_redact(db::txn &, const event &, const write_opts &);
static string_view _index_ephem(db::txn &, const event &, const write_opts &);
}
ircd::string_view
ircd::m::dbs::write(db::txn &txn,
const mutable_buffer &root_out,
const string_view &root_in,
const event &event)
const event &event,
const write_opts &opts)
{
db::txn::append
{
@ -95,28 +102,27 @@ ircd::m::dbs::write(db::txn &txn,
};
if(defined(json::get<"state_key"_>(event)))
return _index_state(txn, root_out, root_in, event);
return _index_state(txn, event, opts);
if(at<"type"_>(event) == "m.room.redaction")
return _index_redact(txn, root_out, root_in, event);
return _index_redact(txn, event, opts);
return _index_ephem(txn, root_in, event);
return _index_ephem(txn, event, opts);
}
ircd::string_view
ircd::m::dbs::_index_ephem(db::txn &txn,
const string_view &state_root_in,
const event &event)
const event &event,
const write_opts &opts)
{
_index__room_events(txn, state_root_in, event);
return state_root_in;
_index__room_events(txn, event, opts, opts.root_in);
return opts.root_in;
}
ircd::string_view
ircd::m::dbs::_index_redact(db::txn &txn,
const mutable_buffer &state_root_out,
const string_view &state_root_in,
const event &event)
const event &event,
const write_opts &opts)
try
{
const auto &target_id
@ -139,16 +145,16 @@ try
if(!defined(json::get<"state_key"_>(target)))
{
_index__room_events(txn, state_root_in, event);
return state_root_in;
_index__room_events(txn, event, opts, opts.root_in);
return opts.root_in;
}
const string_view new_root
{
state_root_in //state::remove(txn, state_root_out, state_root_in, target)
opts.root_in //state::remove(txn, state_root_out, state_root_in, target)
};
_index__room_events(txn, new_root, event);
_index__room_events(txn, event, opts, new_root);
return new_root;
}
catch(const std::exception &e)
@ -163,9 +169,8 @@ catch(const std::exception &e)
ircd::string_view
ircd::m::dbs::_index_state(db::txn &txn,
const mutable_buffer &state_root_out,
const string_view &state_root_in,
const event &event)
const event &event,
const write_opts &opts)
try
{
const auto &type
@ -178,13 +183,14 @@ try
at<"room_id"_>(event)
};
const string_view new_root
const auto &new_root
{
state::insert(txn, state_root_out, state_root_in, event)
state::insert(txn, opts.root_out, opts.root_in, event)
};
_index__room_events(txn, new_root, event);
return new_root;
_index__room_events(txn, event, opts, new_root);
_index__room_origins(txn, event, opts);
return opts.root_in;
}
catch(const std::exception &e)
{
@ -200,8 +206,9 @@ catch(const std::exception &e)
/// You need find/create the right state_root before this.
void
ircd::m::dbs::_index__room_events(db::txn &txn,
const string_view &state_root,
const event &event)
const event &event,
const write_opts &opts,
const string_view &new_root)
{
const ctx::critical_assertion ca;
thread_local char buf[768];
@ -214,8 +221,62 @@ ircd::m::dbs::_index__room_events(db::txn &txn,
{
txn, room_events,
{
key, // key
state_root // val
key, // key
new_root // val
}
};
}
/// Adds the entry for the room_origins column into the txn.
/// This only is affected if opts.present=true
void
ircd::m::dbs::_index__room_origins(db::txn &txn,
const event &event,
const write_opts &opts)
{
if(!opts.present)
return;
if(at<"type"_>(event) != "m.room.member")
return;
const ctx::critical_assertion ca;
thread_local char buf[512];
const string_view &key
{
room_origins_key(buf, at<"room_id"_>(event), at<"origin"_>(event))
};
const string_view &membership
{
json::get<"membership"_>(event)?
string_view{json::get<"membership"_>(event)}:
unquote(at<"content"_>(event).get("membership"))
};
assert(!empty(membership));
db::op op; switch(hash(membership))
{
case hash("join"):
op = db::op::SET;
break;
case hash("ban"):
case hash("leave"):
op = db::op::DELETE;
break;
default:
return;
};
db::txn::append
{
txn, room_origins,
{
op,
key,
}
};
}
@ -536,6 +597,69 @@ ircd::m::dbs::desc::events__room_events
events__room_events__pfx,
};
/// Prefix transform for the events__room_origins
///
/// TODO: This needs The Grammar
///
const ircd::db::prefix_transform
ircd::m::dbs::desc::events__room_origins__pfx
{
"_room_origins",
[](const string_view &key)
{
return key.find(":::") != key.npos;
},
[](const string_view &key)
{
return rsplit(key, ":::").first;
}
};
//TODO: optimize
//TODO: Needs The Gramslam
ircd::string_view
ircd::m::dbs::room_origins_key(const mutable_buffer &out,
const id::room &room_id,
const string_view &origin)
{
size_t len{0};
len = strlcpy(out, room_id);
len = strlcat(out, ":::");
len = strlcat(out, origin);
return { data(out), len };
}
const ircd::database::descriptor
ircd::m::dbs::desc::events__room_origins
{
// name
"_room_origins",
// explanation
R"(### developer note:
the prefix transform is in effect. this column indexes events by
room_id offering an iterable bound of the index prefixed by room_id
)",
// typing (key, value)
{
typeid(ircd::string_view), typeid(ircd::string_view)
},
// options
{},
// comparator
{},
// prefix transform
events__room_origins__pfx,
};
//
// Direct column descriptors
//
@ -1195,4 +1319,8 @@ ircd::m::dbs::desc::events
// (room_id, event_id) => (state_root)
// Sequence of all events for a room, ever.
events__room_events,
// (room_id, origin) => ()
// Sequence of all PRESENTLY JOINED origins for a room.
events__room_origins,
};

View file

@ -658,9 +658,9 @@ bool
ircd::m::room::origins::test(const closure_bool &view)
const
{
db::index index
db::index &index
{
*dbs::events, "origin_joined in room_id"
dbs::room_origins
};
auto it(index.begin(room.room_id));

View file

@ -316,17 +316,24 @@ try
m::room room{room_id, head};
m::room::state state{room};
m::state::id_buffer new_root_buf;
m::dbs::write_opts wopts;
wopts.root_in = state.root_id;
wopts.root_out = new_root_buf;
wopts.present = true;
const auto new_root
{
dbs::write(txn, new_root_buf, state.root_id, event)
dbs::write(txn, event, wopts)
};
}
else if(opts->write)
{
m::state::id_buffer new_root_buf;
m::dbs::write_opts wopts;
wopts.root_out = new_root_buf;
wopts.present = true;
const auto new_root
{
dbs::write(txn, new_root_buf, string_view{}, event)
dbs::write(txn, event, wopts)
};
}