0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-25 08:12:37 +01:00

ircd:Ⓜ️:events: Simplify the for_each iteration interface.

This commit is contained in:
Jason Volk 2019-01-09 17:06:50 -08:00
parent 067a2f8651
commit 6c96e0d785
3 changed files with 78 additions and 112 deletions

View file

@ -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}
{}
};

View file

@ -1611,86 +1611,7 @@ ircd::m::node::room::room(const m::node &node)
//
bool
ircd::m::events::rfor_each(const event::idx &start,
const event_filter &filter,
const closure_bool &closure)
{
auto limit
{
json::get<"limit"_>(filter)?: 32L
};
return rfor_each(start, [&filter, &closure, &limit]
(const event::idx &event_idx, const m::event &event)
-> bool
{
if(!match(filter, event))
return true;
if(!closure(event_idx, event))
return false;
return --limit;
});
}
bool
ircd::m::events::rfor_each(const event::idx &start,
const closure_bool &closure)
{
event::fetch event;
return rfor_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::rfor_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)
};
if(start == uint64_t(-1))
{
for(auto it(column.rbegin(opts)); it; ++it)
if(!closure(byte_view<event::idx>(it->first), it->second))
return false;
return true;
}
auto it
{
column.lower_bound(byte_view<string_view>(start), opts)
};
for(; it; --it)
if(!closure(byte_view<event::idx>(it->first), it->second))
return false;
return true;
}
bool
ircd::m::events::for_each(const event::idx &start,
ircd::m::events::for_each(const range &range,
const event_filter &filter,
const closure_bool &closure)
{
@ -1699,7 +1620,7 @@ ircd::m::events::for_each(const event::idx &start,
json::get<"limit"_>(filter)?: 32L
};
return for_each(start, [&filter, &closure, &limit]
return for_each(range, [&filter, &closure, &limit]
(const event::idx &event_idx, const m::event &event)
-> bool
{
@ -1714,11 +1635,11 @@ ircd::m::events::for_each(const event::idx &start,
}
bool
ircd::m::events::for_each(const event::idx &start,
ircd::m::events::for_each(const range &range,
const closure_bool &closure)
{
event::fetch event;
return for_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))
@ -1729,7 +1650,7 @@ ircd::m::events::for_each(const event::idx &start,
}
bool
ircd::m::events::for_each(const event::idx &start,
ircd::m::events::for_each(const range &range,
const id_closure_bool &closure)
{
static const db::gopts opts
@ -1747,16 +1668,51 @@ ircd::m::events::for_each(const event::idx &start,
dbs::event_column.at(column_idx)
};
auto it
const auto &start{range.first};
const auto &stop{range.second};
const bool ascending
{
start > 0?
column.lower_bound(byte_view<string_view>(start), opts):
column.begin(opts)
start < stop
};
for(; it; ++it)
if(!closure(byte_view<event::idx>(it->first), it->second))
auto it
{
column.lower_bound(byte_view<string_view>(start), opts)
};
// 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;
}
}
else for(; it; ascending? ++it : --it)
{
const event::idx &event_idx
{
byte_view<event::idx>(it->first)
};
if(ascending && event_idx >= stop)
break;
if(!ascending && event_idx <= stop)
break;
if(!closure(event_idx, it->second))
return false;
}
return true;
}

View file

@ -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;;