mirror of
https://github.com/matrix-construct/construct
synced 2024-11-17 23:40:57 +01:00
ircd:Ⓜ️:events: Simplify the for_each iteration interface.
This commit is contained in:
parent
067a2f8651
commit
6c96e0d785
3 changed files with 78 additions and 112 deletions
|
@ -13,16 +13,23 @@
|
|||
|
||||
namespace ircd::m::events
|
||||
{
|
||||
struct range;
|
||||
using id_closure_bool = std::function<bool (const event::idx &, const event::id &)>;
|
||||
using closure_bool = std::function<bool (const event::idx &, const event &)>;
|
||||
|
||||
// counts up from start
|
||||
bool for_each(const event::idx &start, const id_closure_bool &);
|
||||
bool for_each(const event::idx &start, const closure_bool &);
|
||||
bool for_each(const event::idx &start, const event_filter &, const closure_bool &);
|
||||
|
||||
// -1 starts at newest event; counts down
|
||||
bool rfor_each(const event::idx &start, const id_closure_bool &);
|
||||
bool rfor_each(const event::idx &start, const closure_bool &);
|
||||
bool rfor_each(const event::idx &start, const event_filter &, const closure_bool &);
|
||||
bool for_each(const range &, const id_closure_bool &);
|
||||
bool for_each(const range &, const closure_bool &);
|
||||
bool for_each(const range &, const event_filter &, const closure_bool &);
|
||||
}
|
||||
|
||||
/// Range to start (inclusive) and stop (exclusive). If start is greater than
|
||||
/// stop a reverse iteration will occur. -1 (or unsigned max value) can be used
|
||||
/// to start or stop at the end. 0 can be used to start or stop at the beginning.
|
||||
///
|
||||
struct ircd::m::events::range
|
||||
:std::pair<event::idx, event::idx>
|
||||
{
|
||||
range(const event::idx &start, const event::idx &stop = -1)
|
||||
:std::pair<event::idx, event::idx>{start, stop}
|
||||
{}
|
||||
};
|
||||
|
|
118
ircd/m/m.cc
118
ircd/m/m.cc
|
@ -1611,7 +1611,7 @@ ircd::m::node::room::room(const m::node &node)
|
|||
//
|
||||
|
||||
bool
|
||||
ircd::m::events::rfor_each(const event::idx &start,
|
||||
ircd::m::events::for_each(const range &range,
|
||||
const event_filter &filter,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
|
@ -1620,7 +1620,7 @@ ircd::m::events::rfor_each(const event::idx &start,
|
|||
json::get<"limit"_>(filter)?: 32L
|
||||
};
|
||||
|
||||
return rfor_each(start, [&filter, &closure, &limit]
|
||||
return for_each(range, [&filter, &closure, &limit]
|
||||
(const event::idx &event_idx, const m::event &event)
|
||||
-> bool
|
||||
{
|
||||
|
@ -1635,11 +1635,11 @@ ircd::m::events::rfor_each(const event::idx &start,
|
|||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::rfor_each(const event::idx &start,
|
||||
ircd::m::events::for_each(const range &range,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
event::fetch event;
|
||||
return rfor_each(start, id_closure_bool{[&event, &closure]
|
||||
return for_each(range, id_closure_bool{[&event, &closure]
|
||||
(const event::idx &event_idx, const event::id &event_id)
|
||||
{
|
||||
if(!seek(event, event_idx, std::nothrow))
|
||||
|
@ -1650,7 +1650,7 @@ ircd::m::events::rfor_each(const event::idx &start,
|
|||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::rfor_each(const event::idx &start,
|
||||
ircd::m::events::for_each(const range &range,
|
||||
const id_closure_bool &closure)
|
||||
{
|
||||
static const db::gopts opts
|
||||
|
@ -1668,95 +1668,51 @@ ircd::m::events::rfor_each(const event::idx &start,
|
|||
dbs::event_column.at(column_idx)
|
||||
};
|
||||
|
||||
if(start == uint64_t(-1))
|
||||
const auto &start{range.first};
|
||||
const auto &stop{range.second};
|
||||
const bool ascending
|
||||
{
|
||||
for(auto it(column.rbegin(opts)); it; ++it)
|
||||
if(!closure(byte_view<event::idx>(it->first), it->second))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
start < stop
|
||||
};
|
||||
|
||||
auto it
|
||||
{
|
||||
column.lower_bound(byte_view<string_view>(start), opts)
|
||||
};
|
||||
|
||||
for(; it; --it)
|
||||
if(!closure(byte_view<event::idx>(it->first), it->second))
|
||||
// Branch to use a reverse iterator from the end
|
||||
if(!ascending && !it)
|
||||
{
|
||||
for(auto it(column.rbegin(opts)); it; ++it)
|
||||
{
|
||||
const event::idx &event_idx
|
||||
{
|
||||
byte_view<event::idx>(it->first)
|
||||
};
|
||||
|
||||
if(event_idx <= stop)
|
||||
break;
|
||||
|
||||
if(!closure(event_idx, it->second))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::for_each(const event::idx &start,
|
||||
const event_filter &filter,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
auto limit
|
||||
}
|
||||
}
|
||||
else for(; it; ascending? ++it : --it)
|
||||
{
|
||||
json::get<"limit"_>(filter)?: 32L
|
||||
const event::idx &event_idx
|
||||
{
|
||||
byte_view<event::idx>(it->first)
|
||||
};
|
||||
|
||||
return for_each(start, [&filter, &closure, &limit]
|
||||
(const event::idx &event_idx, const m::event &event)
|
||||
-> bool
|
||||
{
|
||||
if(!match(filter, event))
|
||||
return true;
|
||||
if(ascending && event_idx >= stop)
|
||||
break;
|
||||
|
||||
if(!closure(event_idx, event))
|
||||
return false;
|
||||
|
||||
return --limit;
|
||||
});
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::for_each(const event::idx &start,
|
||||
const closure_bool &closure)
|
||||
{
|
||||
event::fetch event;
|
||||
return for_each(start, id_closure_bool{[&event, &closure]
|
||||
(const event::idx &event_idx, const event::id &event_id)
|
||||
{
|
||||
if(!seek(event, event_idx, std::nothrow))
|
||||
return true;
|
||||
|
||||
return closure(event_idx, event);
|
||||
}});
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::events::for_each(const event::idx &start,
|
||||
const id_closure_bool &closure)
|
||||
{
|
||||
static const db::gopts opts
|
||||
{
|
||||
db::get::NO_CACHE
|
||||
};
|
||||
|
||||
static constexpr auto column_idx
|
||||
{
|
||||
json::indexof<event, "event_id"_>()
|
||||
};
|
||||
|
||||
auto &column
|
||||
{
|
||||
dbs::event_column.at(column_idx)
|
||||
};
|
||||
|
||||
auto it
|
||||
{
|
||||
start > 0?
|
||||
column.lower_bound(byte_view<string_view>(start), opts):
|
||||
column.begin(opts)
|
||||
};
|
||||
|
||||
for(; it; ++it)
|
||||
if(!closure(byte_view<event::idx>(it->first), it->second))
|
||||
if(!ascending && event_idx <= stop)
|
||||
break;
|
||||
|
||||
if(!closure(event_idx, it->second))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -5249,36 +5249,39 @@ console_cmd__events(opt &out, const string_view &line)
|
|||
{
|
||||
const params param{line, " ",
|
||||
{
|
||||
"start", "[dir]", "[limit]"
|
||||
"start", "stop"
|
||||
}};
|
||||
|
||||
const uint64_t start
|
||||
const int64_t start
|
||||
{
|
||||
param.at<uint64_t>(0, uint64_t(-1))
|
||||
param.at<int64_t>("start", -1)
|
||||
};
|
||||
|
||||
const char &dir
|
||||
const int64_t stop
|
||||
{
|
||||
param.at(1, "b"_sv).at(0)
|
||||
param.at<int64_t>("stop", start == -1? 0 : -1)
|
||||
};
|
||||
|
||||
size_t limit
|
||||
{
|
||||
param.at<size_t>(2, 32)
|
||||
stop == 0 || stop == -1?
|
||||
32:
|
||||
std::numeric_limits<size_t>::max()
|
||||
};
|
||||
|
||||
const auto closure{[&out, &limit]
|
||||
(const m::event::idx &seq, const m::event &event)
|
||||
{
|
||||
out << seq << " " << pretty_oneline(event) << std::endl;;
|
||||
return --limit;
|
||||
out << seq << " " << pretty_oneline(event) << std::endl;
|
||||
return --limit > 0;
|
||||
}};
|
||||
|
||||
if(dir == 'f')
|
||||
m::events::for_each(start, closure);
|
||||
else
|
||||
m::events::rfor_each(start, closure);
|
||||
const m::events::range range
|
||||
{
|
||||
uint64_t(start), uint64_t(stop)
|
||||
};
|
||||
|
||||
m::events::for_each(range, closure);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5300,7 +5303,7 @@ console_cmd__events__filter(opt &out, const string_view &line)
|
|||
param.at(1)
|
||||
};
|
||||
|
||||
m::events::rfor_each(start, filter, [&out]
|
||||
m::events::for_each({start, 0}, filter, [&out]
|
||||
(const m::event::idx &seq, const m::event &event)
|
||||
{
|
||||
out << seq << " " << pretty_oneline(event) << std::endl;;
|
||||
|
|
Loading…
Reference in a new issue