mirror of
https://github.com/matrix-construct/construct
synced 2024-06-16 08:58:20 +02:00
ircd:Ⓜ️:room::head: Improve interface/linkage for head utils / prev_events generation.
This commit is contained in:
parent
1a1939e2c7
commit
c2966275c6
|
@ -43,6 +43,13 @@ struct ircd::m::room::head
|
|||
using closure = std::function<void (const event::idx &, const event::id &)>;
|
||||
using closure_bool = std::function<bool (const event::idx &, const event::id &)>;
|
||||
|
||||
static size_t reset(const head &);
|
||||
static size_t rebuild(const head &);
|
||||
static void modify(const event::id &, const db::op &, const bool &);
|
||||
static int64_t make_refs(const head &, json::stack::array &, const size_t &, const bool &);
|
||||
static bool for_each(const head &, const closure_bool &);
|
||||
|
||||
public:
|
||||
m::room room;
|
||||
|
||||
bool for_each(const closure_bool &) const;
|
||||
|
@ -50,6 +57,9 @@ struct ircd::m::room::head
|
|||
bool has(const event::id &) const;
|
||||
size_t count() const;
|
||||
|
||||
int64_t make_refs(json::stack::array &, const size_t &, const bool &) const;
|
||||
std::pair<json::array, int64_t> make_refs(const mutable_buffer &, const size_t &, const bool &) const;
|
||||
|
||||
head(const m::room &room)
|
||||
:room{room}
|
||||
{}
|
||||
|
|
108
ircd/m_room.cc
108
ircd/m_room.cc
|
@ -2036,6 +2036,35 @@ const
|
|||
// room::head
|
||||
//
|
||||
|
||||
std::pair<ircd::json::array, int64_t>
|
||||
ircd::m::room::head::make_refs(const mutable_buffer &buf,
|
||||
const size_t &limit,
|
||||
const bool &need_top)
|
||||
const
|
||||
{
|
||||
json::stack out{buf};
|
||||
json::stack::array array{out};
|
||||
const auto depth
|
||||
{
|
||||
make_refs(array, limit, need_top)
|
||||
};
|
||||
array.~array();
|
||||
return
|
||||
{
|
||||
json::array{out.completed()},
|
||||
depth
|
||||
};
|
||||
}
|
||||
|
||||
int64_t
|
||||
ircd::m::room::head::make_refs(json::stack::array &out,
|
||||
const size_t &limit,
|
||||
const bool &need_top)
|
||||
const
|
||||
{
|
||||
return make_refs(*this, out, limit, need_top);
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::room::head::count()
|
||||
const
|
||||
|
@ -2081,33 +2110,78 @@ bool
|
|||
ircd::m::room::head::for_each(const closure_bool &closure)
|
||||
const
|
||||
{
|
||||
auto &index
|
||||
return for_each(*this, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::room::head::for_each(const head &h,
|
||||
const closure_bool &c)
|
||||
{
|
||||
using prototype = bool (const head &, const closure_bool &);
|
||||
|
||||
static mods::import<prototype> call
|
||||
{
|
||||
dbs::room_head
|
||||
"m_room", "ircd::m::room::head::for_each"
|
||||
};
|
||||
|
||||
auto it
|
||||
return call(h, c);
|
||||
}
|
||||
|
||||
int64_t
|
||||
ircd::m::room::head::make_refs(const head &h,
|
||||
json::stack::array &a,
|
||||
const size_t &limit,
|
||||
const bool &need_top)
|
||||
{
|
||||
using prototype = int64_t (const head &, json::stack::array &, const size_t &, const bool &);
|
||||
|
||||
static mods::import<prototype> call
|
||||
{
|
||||
index.begin(room.room_id)
|
||||
"m_room", "ircd::m::room::head::make_refs"
|
||||
};
|
||||
|
||||
for(; it; ++it)
|
||||
return call(h, a, limit, need_top);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::room::head::modify(const event::id &event_id,
|
||||
const db::op &op,
|
||||
const bool &refs)
|
||||
{
|
||||
using prototype = void (const event::id &, const db::op &, const bool &);
|
||||
|
||||
static mods::import<prototype> call
|
||||
{
|
||||
const event::id &event_id
|
||||
{
|
||||
dbs::room_head_key(it->first)
|
||||
};
|
||||
"m_room", "ircd::m::room::head::modify"
|
||||
};
|
||||
|
||||
const event::idx &event_idx
|
||||
{
|
||||
byte_view<event::idx>{it->second}
|
||||
};
|
||||
return call(event_id, op, refs);
|
||||
}
|
||||
|
||||
if(!closure(event_idx, event_id))
|
||||
return false;
|
||||
}
|
||||
size_t
|
||||
ircd::m::room::head::rebuild(const head &h)
|
||||
{
|
||||
using prototype = size_t (const head &);
|
||||
|
||||
return true;
|
||||
static mods::import<prototype> call
|
||||
{
|
||||
"m_room", "ircd::m::room::head::rebuild"
|
||||
};
|
||||
|
||||
return call(h);
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::room::head::reset(const head &h)
|
||||
{
|
||||
using prototype = size_t (const head &);
|
||||
|
||||
static mods::import<prototype> call
|
||||
{
|
||||
"m_room", "ircd::m::room::head::reset"
|
||||
};
|
||||
|
||||
return call(h);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -5033,19 +5033,20 @@ console_cmd__stage__make_prev(opt &out, const string_view &line)
|
|||
stage.at(id)
|
||||
};
|
||||
|
||||
using prototype = std::pair<json::array, int64_t> (const m::room &,
|
||||
const mutable_buffer &,
|
||||
const size_t &,
|
||||
const bool &);
|
||||
static mods::import<prototype> make_prev__buf
|
||||
const m::room room
|
||||
{
|
||||
"m_room", "make_prev__buf"
|
||||
at<"room_id"_>(event)
|
||||
};
|
||||
|
||||
const m::room::head head
|
||||
{
|
||||
room
|
||||
};
|
||||
|
||||
thread_local char buf[8192];
|
||||
const auto prev
|
||||
{
|
||||
make_prev__buf(m::room{at<"room_id"_>(event)}, buf, limit, true)
|
||||
head.make_refs(buf, limit, true)
|
||||
};
|
||||
|
||||
json::get<"prev_events"_>(event) = prev.first;
|
||||
|
@ -6790,15 +6791,14 @@ console_cmd__room__head__rebuild(opt &out, const string_view &line)
|
|||
room_id
|
||||
};
|
||||
|
||||
using prototype = size_t (const m::room &);
|
||||
static mods::import<prototype> head__rebuild
|
||||
const m::room::head head
|
||||
{
|
||||
"m_room", "head__rebuild"
|
||||
room
|
||||
};
|
||||
|
||||
const size_t count
|
||||
{
|
||||
head__rebuild(room)
|
||||
head.rebuild(head)
|
||||
};
|
||||
|
||||
out << "done " << count << std::endl;
|
||||
|
@ -6818,13 +6818,7 @@ console_cmd__room__head__add(opt &out, const string_view &line)
|
|||
param.at(0)
|
||||
};
|
||||
|
||||
using prototype = void (const m::event::id &, const db::op &, const bool &);
|
||||
static mods::import<prototype> head__modify
|
||||
{
|
||||
"m_room", "head__modify"
|
||||
};
|
||||
|
||||
head__modify(event_id, db::op::SET, true);
|
||||
m::room::head::modify(event_id, db::op::SET, true);
|
||||
out << "Added " << event_id << " to head " << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
@ -6842,13 +6836,7 @@ console_cmd__room__head__del(opt &out, const string_view &line)
|
|||
param.at(0)
|
||||
};
|
||||
|
||||
using prototype = void (const m::event::id &, const db::op &, const bool &);
|
||||
static mods::import<prototype> head__modify
|
||||
{
|
||||
"m_room", "head__modify"
|
||||
};
|
||||
|
||||
head__modify(event_id, db::op::DELETE, true);
|
||||
m::room::head::modify(event_id, db::op::DELETE, true);
|
||||
out << "Deleted " << event_id << " from head (if existed)" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
@ -6900,15 +6888,14 @@ console_cmd__room__head__reset(opt &out, const string_view &line)
|
|||
room_id
|
||||
};
|
||||
|
||||
using prototype = size_t (const m::room &);
|
||||
static mods::import<prototype> head__reset
|
||||
const m::room::head head
|
||||
{
|
||||
"m_room", "head__reset"
|
||||
room
|
||||
};
|
||||
|
||||
const size_t count
|
||||
{
|
||||
head__reset(room)
|
||||
head.reset(head)
|
||||
};
|
||||
|
||||
out << "done " << count << std::endl;
|
||||
|
|
|
@ -287,12 +287,151 @@ ircd::m::room::auth::make_refs(const auth &auth,
|
|||
fetch("m.room.member", user_id);
|
||||
}
|
||||
|
||||
extern "C" int64_t
|
||||
make_prev(const m::room &room,
|
||||
json::stack::array &out,
|
||||
size_t limit,
|
||||
bool need_tophead = true)
|
||||
size_t
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::room::head::rebuild(const head &head)
|
||||
{
|
||||
size_t ret{0};
|
||||
const auto &room{head.room};
|
||||
const m::room::state state{room};
|
||||
const auto create_idx
|
||||
{
|
||||
state.get("m.room.create")
|
||||
};
|
||||
|
||||
static const m::event::fetch::opts fopts
|
||||
{
|
||||
{ db::get::NO_CACHE }
|
||||
};
|
||||
|
||||
m::room::messages it
|
||||
{
|
||||
room, create_idx, &fopts
|
||||
};
|
||||
|
||||
if(!it)
|
||||
return ret;
|
||||
|
||||
db::txn txn
|
||||
{
|
||||
*m::dbs::events
|
||||
};
|
||||
|
||||
m::dbs::write_opts opts;
|
||||
opts.op = db::op::SET;
|
||||
opts.room_head = true;
|
||||
opts.room_refs = true;
|
||||
for(; it; ++it)
|
||||
{
|
||||
const m::event &event{*it};
|
||||
opts.event_idx = it.event_idx();
|
||||
m::dbs::_index__room_head(txn, event, opts);
|
||||
++ret;
|
||||
}
|
||||
|
||||
txn();
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::room::head::reset(const head &head)
|
||||
{
|
||||
size_t ret{0};
|
||||
const auto &room{head.room};
|
||||
m::room::messages it{room};
|
||||
if(!it)
|
||||
return ret;
|
||||
|
||||
// Replacement will be the single new head
|
||||
const m::event replacement
|
||||
{
|
||||
*it
|
||||
};
|
||||
|
||||
db::txn txn
|
||||
{
|
||||
*m::dbs::events
|
||||
};
|
||||
|
||||
// Iterate all of the existing heads with a delete operation
|
||||
m::dbs::write_opts opts;
|
||||
opts.op = db::op::DELETE;
|
||||
opts.room_head = true;
|
||||
m::room::head{room}.for_each([&room, &opts, &txn, &ret]
|
||||
(const m::event::idx &event_idx, const m::event::id &event_id)
|
||||
{
|
||||
const m::event::fetch event
|
||||
{
|
||||
event_idx, std::nothrow
|
||||
};
|
||||
|
||||
if(!event.valid)
|
||||
{
|
||||
log::derror
|
||||
{
|
||||
m::log, "Invalid event '%s' idx %lu in head for %s",
|
||||
string_view{event_id},
|
||||
event_idx,
|
||||
string_view{room.room_id}
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
opts.event_idx = event_idx;
|
||||
m::dbs::_index__room_head(txn, event, opts);
|
||||
++ret;
|
||||
});
|
||||
|
||||
// Finally add the replacement to the txn
|
||||
opts.op = db::op::SET;
|
||||
opts.event_idx = it.event_idx();
|
||||
m::dbs::_index__room_head(txn, replacement, opts);
|
||||
|
||||
// Commit txn
|
||||
txn();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::room::head::modify(const m::event::id &event_id,
|
||||
const db::op &op,
|
||||
const bool &refs)
|
||||
{
|
||||
const m::event::fetch event
|
||||
{
|
||||
event_id
|
||||
};
|
||||
|
||||
db::txn txn
|
||||
{
|
||||
*m::dbs::events
|
||||
};
|
||||
|
||||
// Iterate all of the existing heads with a delete operation
|
||||
m::dbs::write_opts opts;
|
||||
opts.op = op;
|
||||
opts.room_head = true;
|
||||
opts.room_refs = refs;
|
||||
opts.event_idx = event.event_idx;
|
||||
m::dbs::_index__room_head(txn, event, opts);
|
||||
|
||||
// Commit txn
|
||||
txn();
|
||||
}
|
||||
|
||||
int64_t
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::room::head::make_refs(const head &head,
|
||||
json::stack::array &out,
|
||||
const size_t &_limit,
|
||||
const bool &_need_tophead)
|
||||
{
|
||||
size_t limit{_limit};
|
||||
bool need_tophead{_need_tophead};
|
||||
const auto &room{head.room};
|
||||
const auto top_head
|
||||
{
|
||||
need_tophead?
|
||||
|
@ -302,7 +441,6 @@ make_prev(const m::room &room,
|
|||
|
||||
int64_t depth{-1};
|
||||
m::event::fetch event;
|
||||
const m::room::head head{room};
|
||||
head.for_each(m::room::head::closure_bool{[&]
|
||||
(const m::event::idx &idx, const m::event::id &event_id)
|
||||
{
|
||||
|
@ -345,23 +483,33 @@ make_prev(const m::room &room,
|
|||
return depth;
|
||||
}
|
||||
|
||||
extern "C" std::pair<json::array, int64_t>
|
||||
make_prev__buf(const m::room &room,
|
||||
const mutable_buffer &buf,
|
||||
const size_t &limit,
|
||||
const bool &need_tophead)
|
||||
bool
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::room::head::for_each(const head &head,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
int64_t depth;
|
||||
json::stack ps{buf};
|
||||
auto it
|
||||
{
|
||||
json::stack::array top{ps};
|
||||
depth = make_prev(room, top, limit, need_tophead);
|
||||
dbs::room_head.begin(head.room.room_id)
|
||||
};
|
||||
|
||||
for(; it; ++it)
|
||||
{
|
||||
const event::id &event_id
|
||||
{
|
||||
dbs::room_head_key(it->first)
|
||||
};
|
||||
|
||||
const event::idx &event_idx
|
||||
{
|
||||
byte_view<event::idx>{it->second}
|
||||
};
|
||||
|
||||
if(!closure(event_idx, event_id))
|
||||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
{
|
||||
json::array{ps.completed()}, depth
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<bool, int64_t>
|
||||
|
@ -678,140 +826,6 @@ ircd::m::room::state::prefetch(const state &state,
|
|||
return ret;
|
||||
}
|
||||
|
||||
extern "C" size_t
|
||||
head__rebuild(const m::room &room)
|
||||
{
|
||||
size_t ret{0};
|
||||
const m::room::state state{room};
|
||||
const auto create_idx
|
||||
{
|
||||
state.get("m.room.create")
|
||||
};
|
||||
|
||||
static const m::event::fetch::opts fopts
|
||||
{
|
||||
{ db::get::NO_CACHE }
|
||||
};
|
||||
|
||||
m::room::messages it
|
||||
{
|
||||
room, create_idx, &fopts
|
||||
};
|
||||
|
||||
if(!it)
|
||||
return ret;
|
||||
|
||||
db::txn txn
|
||||
{
|
||||
*m::dbs::events
|
||||
};
|
||||
|
||||
m::dbs::write_opts opts;
|
||||
opts.op = db::op::SET;
|
||||
opts.room_head = true;
|
||||
opts.room_refs = true;
|
||||
for(; it; ++it)
|
||||
{
|
||||
const m::event &event{*it};
|
||||
opts.event_idx = it.event_idx();
|
||||
m::dbs::_index__room_head(txn, event, opts);
|
||||
++ret;
|
||||
}
|
||||
|
||||
txn();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" size_t
|
||||
head__reset(const m::room &room)
|
||||
{
|
||||
size_t ret{0};
|
||||
m::room::messages it
|
||||
{
|
||||
room
|
||||
};
|
||||
|
||||
if(!it)
|
||||
return ret;
|
||||
|
||||
// Replacement will be the single new head
|
||||
const m::event replacement
|
||||
{
|
||||
*it
|
||||
};
|
||||
|
||||
db::txn txn
|
||||
{
|
||||
*m::dbs::events
|
||||
};
|
||||
|
||||
// Iterate all of the existing heads with a delete operation
|
||||
m::dbs::write_opts opts;
|
||||
opts.op = db::op::DELETE;
|
||||
opts.room_head = true;
|
||||
m::room::head{room}.for_each([&room, &opts, &txn, &ret]
|
||||
(const m::event::idx &event_idx, const m::event::id &event_id)
|
||||
{
|
||||
const m::event::fetch event
|
||||
{
|
||||
event_idx, std::nothrow
|
||||
};
|
||||
|
||||
if(!event.valid)
|
||||
{
|
||||
log::derror
|
||||
{
|
||||
m::log, "Invalid event '%s' idx %lu in head for %s",
|
||||
string_view{event_id},
|
||||
event_idx,
|
||||
string_view{room.room_id}
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
opts.event_idx = event_idx;
|
||||
m::dbs::_index__room_head(txn, event, opts);
|
||||
++ret;
|
||||
});
|
||||
|
||||
// Finally add the replacement to the txn
|
||||
opts.op = db::op::SET;
|
||||
opts.event_idx = it.event_idx();
|
||||
m::dbs::_index__room_head(txn, replacement, opts);
|
||||
|
||||
// Commit txn
|
||||
txn();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
head__modify(const m::event::id &event_id,
|
||||
const db::op &op,
|
||||
const bool &refs)
|
||||
{
|
||||
const m::event::fetch event
|
||||
{
|
||||
event_id
|
||||
};
|
||||
|
||||
db::txn txn
|
||||
{
|
||||
*m::dbs::events
|
||||
};
|
||||
|
||||
// Iterate all of the existing heads with a delete operation
|
||||
m::dbs::write_opts opts;
|
||||
opts.op = op;
|
||||
opts.room_head = true;
|
||||
opts.room_refs = refs;
|
||||
opts.event_idx = index(event);
|
||||
m::dbs::_index__room_head(txn, event, opts);
|
||||
|
||||
// Commit txn
|
||||
txn();
|
||||
}
|
||||
|
||||
extern "C" size_t
|
||||
dagree_histogram(const m::room &room,
|
||||
std::vector<size_t> &vec)
|
||||
|
@ -902,7 +916,7 @@ room_herd(const m::room &room,
|
|||
for(const m::event::id &event_id : event_ids)
|
||||
if(exists(event_id))
|
||||
{
|
||||
head__modify(event_id, db::op::SET, false);
|
||||
m::room::head::modify(event_id, db::op::SET, false);
|
||||
++i;
|
||||
}
|
||||
|
||||
|
|
|
@ -180,20 +180,17 @@ ircd::m::vm::eval__commit_room(eval &eval,
|
|||
event, { "room_id", room.room_id }
|
||||
};
|
||||
|
||||
using prev_prototype = std::pair<json::array, int64_t> (const m::room &,
|
||||
const mutable_buffer &,
|
||||
const size_t &,
|
||||
const bool &);
|
||||
static mods::import<prev_prototype> make_prev__buf
|
||||
const m::room::head head
|
||||
{
|
||||
"m_room", "make_prev__buf"
|
||||
room
|
||||
};
|
||||
|
||||
const bool need_tophead{event.at("type") != "m.room.create"};
|
||||
const unique_buffer<mutable_buffer> prev_buf{8192};
|
||||
static const size_t prev_limit{16};
|
||||
const auto prev
|
||||
{
|
||||
make_prev__buf(room, prev_buf, 16, need_tophead)
|
||||
head.make_refs(prev_buf, prev_limit, need_tophead)
|
||||
};
|
||||
|
||||
const auto &prev_events{prev.first};
|
||||
|
|
Loading…
Reference in a new issue