diff --git a/include/ircd/db/comparator.h b/include/ircd/db/comparator.h index 9db3efb95..9519271eb 100644 --- a/include/ircd/db/comparator.h +++ b/include/ircd/db/comparator.h @@ -28,6 +28,8 @@ namespace ircd::db struct comparator; struct cmp_int64_t; + struct reverse_cmp_int64_t; + struct cmp_string_view; struct reverse_cmp_string_view; } @@ -39,24 +41,6 @@ struct ircd::db::comparator std::function equal; }; -struct ircd::db::reverse_cmp_string_view -:db::comparator -{ - static bool less(const string_view &a, const string_view &b) - { - return std::memcmp(a.data(), b.data(), std::min(a.size(), b.size())) > 0; - } - - static bool equal(const string_view &a, const string_view &b) - { - return a == b; - } - - reverse_cmp_string_view() - :db::comparator{"reverse_string_view", &less, &equal} - {} -}; - struct ircd::db::cmp_string_view :db::comparator { @@ -75,24 +59,47 @@ struct ircd::db::cmp_string_view {} }; +struct ircd::db::reverse_cmp_string_view +:db::comparator +{ + static bool less(const string_view &a, const string_view &b) + { + /// RocksDB sez things will not work correctly unless a shorter string + /// result returns less than a longer string even if one intends some + /// reverse ordering + if(a.size() < b.size()) + return true; + + /// Furthermore, b.size() < a.size() returning false from this function + /// appears to not be correct. The reversal also has to also come in + /// the form of a bytewise forward iteration. + return std::memcmp(a.data(), b.data(), std::min(a.size(), b.size())) > 0; + } + + static bool equal(const string_view &a, const string_view &b) + { + return a == b; + } + + reverse_cmp_string_view() + :db::comparator{"reverse_string_view", &less, &equal} + {} +}; + struct ircd::db::cmp_int64_t :db::comparator { static bool less(const string_view &sa, const string_view &sb) { - assert(sa.size() == sizeof(int64_t)); - assert(sb.size() == sizeof(int64_t)); - const byte_view a{sa}; - const byte_view b{sb}; + assert(sa.size() == sizeof(int64_t) && sb.size() == sizeof(int64_t)); + const byte_view a{sa}, b{sb}; return a < b; } static bool equal(const string_view &sa, const string_view &sb) { - assert(sa.size() == sizeof(int64_t)); - assert(sb.size() == sizeof(int64_t)); - const byte_view a{sa}; - const byte_view b{sb}; + assert(sa.size() == sizeof(int64_t) && sb.size() == sizeof(int64_t)); + const byte_view a{sa}, b{sb}; return a == b; } @@ -100,3 +107,21 @@ struct ircd::db::cmp_int64_t :db::comparator{"int64_t", &less, &equal} {} }; + +struct ircd::db::reverse_cmp_int64_t +:db::comparator +{ + static bool less(const string_view &a, const string_view &b) + { + return !cmp_int64_t::less(a, b); + } + + static bool equal(const string_view &a, const string_view &b) + { + return cmp_int64_t::equal(a, b); + } + + reverse_cmp_int64_t() + :db::comparator{"reverse_int64_t", &less, &equal} + {} +};