From 9b00c65ef6ff2e26346ef133db7a1ed8af6eb41e Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 16 Apr 2019 14:42:28 -0700 Subject: [PATCH] ircd::m::events: Add additional lighter-weight event_idx iteration tools. --- include/ircd/m/events.h | 3 ++ ircd/m.cc | 89 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/include/ircd/m/events.h b/include/ircd/m/events.h index b203a0a38..72be159f6 100644 --- a/include/ircd/m/events.h +++ b/include/ircd/m/events.h @@ -20,6 +20,9 @@ namespace ircd::m::events bool for_each_in_sender(const id::user &, const closure_sender_bool &); bool for_each_in_origin(const string_view &, const closure_sender_bool &); + bool for_each(const range &, const event::closure_idx_bool &); + bool for_each(const range &, const event_filter &, const event::closure_idx_bool &); + bool for_each(const range &, const closure_bool &); bool for_each(const range &, const event_filter &, const closure_bool &); } diff --git a/ircd/m.cc b/ircd/m.cc index dd6e38807..9e005900e 100644 --- a/ircd/m.cc +++ b/ircd/m.cc @@ -2541,6 +2541,95 @@ ircd::m::events::for_each(const range &range, return true; } +///TODO: This impl is temp. Need better dispatching based on filter before +///TODO: fetching event. +bool +ircd::m::events::for_each(const range &range, + const event_filter &filter, + const event::closure_idx_bool &closure) +{ + auto limit + { + json::get<"limit"_>(filter)?: 32L + }; + + return for_each(range, event::closure_idx_bool{[&filter, &closure, &limit, &range] + (const event::idx &event_idx) + -> bool + { + const m::event::fetch event + { + event_idx, std::nothrow, range.fopts? *range.fopts : event::fetch::default_opts + }; + + if(!event.valid) + return true; + + if(!match(filter, event)) + return true; + + if(!closure(event_idx)) + return false; + + return --limit; + }}); + + return true; +} + +bool +ircd::m::events::for_each(const range &range, + const event::closure_idx_bool &closure) +{ + const bool ascending + { + range.first <= range.second + }; + + auto start + { + ascending? + range.first: + std::min(range.first, vm::sequence::retired) + }; + + const auto stop + { + ascending? + std::min(range.second, vm::sequence::retired + 1): + range.second + }; + + auto &column + { + dbs::event_json + }; + + auto it + { + column.lower_bound(byte_view(start)) + }; + + for(; bool(it); ascending? ++it : --it) + { + const event::idx event_idx + { + byte_view(it->first) + }; + + if(ascending && event_idx >= stop) + break; + + if(!ascending && event_idx <= stop) + break; + + if(!closure(event_idx)) + return false; + } + + return true; +} + bool ircd::m::events::for_each_in_origin(const string_view &origin, const closure_sender_bool &closure)