From 9c03fcdb959de10a91d043dc2cf877d226138d1f Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 5 Feb 2018 11:49:40 -0800 Subject: [PATCH] ircd::m::state: Basic util suite. --- include/ircd/m/state.h | 19 +++++++----- ircd/m/state.cc | 70 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/include/ircd/m/state.h b/include/ircd/m/state.h index 8e11ce2b9..dccf3f213 100644 --- a/include/ircd/m/state.h +++ b/include/ircd/m/state.h @@ -28,9 +28,6 @@ namespace ircd::m::state struct init; struct node; - using id_closure = std::function; - using node_closure = std::function; - constexpr size_t ID_MAX_SZ { 64 }; constexpr size_t KEY_MAX_SZ { 256 + 256 + 16 }; constexpr size_t VAL_MAX_SZ { 256 + 16 }; @@ -40,11 +37,16 @@ namespace ircd::m::state constexpr size_t NODE_MAX_DEG { NODE_MAX_KEY + 1 }; // tmp for now constexpr int8_t MAX_HEIGHT { 16 }; // good for few mil at any degree :) + using id_closure = std::function; + using node_closure = std::function; + using search_closure = std::function; + using iter_closure = std::function; + using iter_bool_closure = std::function; + int keycmp(const json::array &a, const json::array &b); - json::array make_key(const mutable_buffer &out, const string_view &type, const string_view &state_key); - string_view set_node(db::txn &txn, const mutable_buffer &id, const json::object &node); + string_view set_node(db::txn &txn, const mutable_buffer &id, const json::object &node); void get_node(const string_view &id, const node_closure &); string_view get_head(const mutable_buffer &out, const id::room &); @@ -54,8 +56,11 @@ namespace ircd::m::state string_view insert(db::txn &, const mutable_buffer &head, const id::room &, const string_view &type, const string_view &state_key, const id::event &); string_view insert(db::txn &, const mutable_buffer &head, const event &); - using search_closure = std::function; - bool dfs(const string_view &node_id, const search_closure &); + bool dfs(const string_view &head, const search_closure &); + bool each(const string_view &head, const iter_bool_closure &); + bool each(const string_view &head, const string_view &type, const iter_bool_closure &); + size_t count(const string_view &head, const iter_bool_closure &); + size_t count(const string_view &head); void get(const string_view &head, const json::array &key, const id_closure &); void get(const string_view &head, const string_view &type, const string_view &state_key, const id_closure &); diff --git a/ircd/m/state.cc b/ircd/m/state.cc index 1eb2bc610..38d39b794 100644 --- a/ircd/m/state.cc +++ b/ircd/m/state.cc @@ -87,17 +87,69 @@ ircd::m::state::get(const string_view &head, }); } +size_t +ircd::m::state::count(const string_view &head) +{ + return count(head, [] + (const json::array &key, const string_view &val) + { + return true; + }); +} + +size_t +ircd::m::state::count(const string_view &head, + const iter_bool_closure &closure) +{ + size_t ret{0}; + each(head, [&ret, &closure] + (const json::array &key, const string_view &val) + { + ret += closure(key, val); + return true; + }); + + return ret; +} + +///TODO: optimize +bool +ircd::m::state::each(const string_view &head, + const string_view &type, + const iter_bool_closure &closure) +{ + return each(head, [&type, &closure] + (const json::array &key, const string_view &val) + { + if(unquote(key.at(0)) != type) + return true; + + return closure(key, val); + }); +} + +bool +ircd::m::state::each(const string_view &head, + const iter_bool_closure &closure) +{ + return dfs(head, [&closure] + (const json::array &key, const string_view &val, const uint &, const uint &) + { + return closure(key, val); + }); +} + namespace ircd::m::state { bool _dfs_recurse(const search_closure &, const node &, int &); } bool -ircd::m::state::dfs(const string_view &node_id, +ircd::m::state::dfs(const string_view &head, const search_closure &closure) { - bool ret{false}; - get_node(node_id, [&closure, &ret] + bool ret{true}; + get_node(head, [&closure, &ret] (const auto &node) { int depth(-1); @@ -128,27 +180,27 @@ ircd::m::state::_dfs_recurse(const search_closure &closure, if(!empty(child)) { - bool ret{false}; + bool ret{true}; get_node(child, [&closure, &depth, &ret] (const auto &node) { ret = _dfs_recurse(closure, node, depth); }); - if(ret) - return true; + if(!ret) + return ret; } if(rep.kn > pos) { const auto &key{rep.keys[pos]}; const auto &val{unquote(rep.vals[pos])}; - if(closure(key, val, depth, pos)) - return true; + if(!closure(key, val, depth, pos)) + return false; } } - return false; + return true; } // Internal insertion operations