From 0da4dec13cae6bc03978e8ca7bb48bda92ab450c Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 9 Jun 2018 14:32:46 -0700 Subject: [PATCH] ircd::m::event: Add topological before; improve prev iteration closure; reorg some util. --- include/ircd/m/event.h | 10 +++- ircd/m/event.cc | 122 ++++++++++++++++++++++++++--------------- 2 files changed, 86 insertions(+), 46 deletions(-) diff --git a/include/ircd/m/event.h b/include/ircd/m/event.h index 1798b2dd4..581055c31 100644 --- a/include/ircd/m/event.h +++ b/include/ircd/m/event.h @@ -28,14 +28,17 @@ namespace ircd::m bool bad(const id::event &, uint64_t &); bool bad(const id::event &); + // Equality tests the event_id only! know this. + bool operator==(const event &a, const event &b); + // Depth comparison; expect unstable sorting. bool operator<(const event &, const event &); bool operator>(const event &, const event &); bool operator<=(const event &, const event &); bool operator>=(const event &, const event &); - // Equality tests the event_id only! know this. - bool operator==(const event &a, const event &b); + // Topological + bool before(const event &a, const event &b); // A directly referenced by B id::event make_id(const event &, id::event::buf &buf, const const_buffer &hash); id::event make_id(const event &, id::event::buf &buf); @@ -142,7 +145,8 @@ struct ircd::m::event namespace ircd::m { - void for_each(const event::prev &, const std::function &); + bool for_each(const event::prev &, const event::id::closure_bool &); + void for_each(const event::prev &, const event::id::closure &); size_t degree(const event::prev &); size_t count(const event::prev &); diff --git a/ircd/m/event.cc b/ircd/m/event.cc index e5b61f954..c755d0ffd 100644 --- a/ircd/m/event.cc +++ b/ircd/m/event.cc @@ -255,10 +255,27 @@ ircd::m::make_id(const event &event, } bool -ircd::m::operator==(const event &a, const event &b) +ircd::m::before(const event &a, + const event &b) { - assert(json::get<"room_id"_>(a) == json::get<"room_id"_>(b)); - return at<"event_id"_>(a) == at<"event_id"_>(b); + const event::prev prev_b{b}; + const json::array &prev_b_events + { + json::get<"prev_events"_>(prev_b) + }; + + for(const json::array &prev_event : prev_b_events) + { + const event::id prev_event_id + { + unquote(prev_event.at(0)) + }; + + if(prev_event_id == at<"event_id"_>(a)) + return true; + } + + return false; } bool @@ -289,6 +306,13 @@ ircd::m::operator<(const event &a, const event &b) return at<"depth"_>(a) < at<"depth"_>(b); } +bool +ircd::m::operator==(const event &a, const event &b) +{ + assert(json::get<"room_id"_>(a) == json::get<"room_id"_>(b)); + return at<"event_id"_>(a) == at<"event_id"_>(b); +} + bool ircd::m::bad(const id::event &event_id) { @@ -378,46 +402,6 @@ ircd::m::degree(const event &event) return degree(event::prev{event}); } -size_t -ircd::m::degree(const event::prev &prev) -{ - size_t ret{0}; - json::for_each(prev, [&ret] - (const auto &, const json::array &prevs) - { - ret += prevs.count(); - }); - - return ret; -} - -size_t -ircd::m::count(const event::prev &prev) -{ - size_t ret{0}; - m::for_each(prev, [&ret](const event::id &event_id) - { - ++ret; - }); - - return ret; -} - -void -ircd::m::for_each(const event::prev &prev, - const std::function &closure) -{ - json::for_each(prev, [&closure] - (const auto &key, const json::array &prevs) - { - for(const json::array &prev : prevs) - { - const event::id &id{unquote(prev[0])}; - closure(id); - } - }); -} - std::string ircd::m::pretty(const event::prev &prev) { @@ -518,6 +502,58 @@ ircd::m::pretty_oneline(std::ostream &s, return s; } +size_t +ircd::m::degree(const event::prev &prev) +{ + size_t ret{0}; + json::for_each(prev, [&ret] + (const auto &, const json::array &prevs) + { + ret += prevs.count(); + }); + + return ret; +} + +size_t +ircd::m::count(const event::prev &prev) +{ + size_t ret{0}; + m::for_each(prev, [&ret](const event::id &event_id) + { + ++ret; + }); + + return ret; +} + +void +ircd::m::for_each(const event::prev &prev, + const event::id::closure &closure) +{ + m::for_each(prev, event::id::closure_bool{[&closure] + (const event::id &event_id) + { + closure(event_id); + return true; + }}); +} + +bool +ircd::m::for_each(const event::prev &prev, + const event::id::closure_bool &closure) +{ + return json::until(prev, [&closure] + (const auto &key, const json::array &prevs) + { + for(const json::array &prev : prevs) + if(!closure(event::id(unquote(prev.at(0))))) + return false; + + return true; + }); +} + bool ircd::m::my(const event &event) {