From eee3e6eb6be31843efc8bf81f5345d8c81405d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 18 Nov 2023 02:32:55 +0300 Subject: [PATCH] =?UTF-8?q?mdbx++:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20`compare=5Fpositions()`=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BA=D1=83=D1=80=D1=81=D0=BE=D1=80=D0=BE=D0=B2?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mdbx.h++ | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/mdbx.c++ | 5 +++++ 2 files changed, 49 insertions(+) diff --git a/mdbx.h++ b/mdbx.h++ index 9be7e341..c973573b 100644 --- a/mdbx.h++ +++ b/mdbx.h++ @@ -567,6 +567,7 @@ MDBX_DECLARE_EXCEPTION(dangling_map_id); [[noreturn]] LIBMDBX_API void throw_out_range(); [[noreturn]] LIBMDBX_API void throw_allocators_mismatch(); [[noreturn]] LIBMDBX_API void throw_bad_value_size(); +[[noreturn]] LIBMDBX_API void throw_incomparable_cursors(); static MDBX_CXX14_CONSTEXPR size_t check_length(size_t bytes); static MDBX_CXX14_CONSTEXPR size_t check_length(size_t headroom, size_t payload); @@ -4339,6 +4340,34 @@ public: friend MDBX_CXX11_CONSTEXPR bool operator!=(const cursor &a, const cursor &b) noexcept; + friend inline int compare_position_nothrow(const cursor &left, + const cursor &right, + bool ignore_nested) noexcept; + friend inline int compare_position(const cursor &left, const cursor &right, + bool ignore_nested); + + bool is_before_than(const cursor &other, bool ignore_nested = false) const { + return compare_position(*this, other, ignore_nested) < 0; + } + + bool is_same_or_before_than(const cursor &other, + bool ignore_nested = false) const { + return compare_position(*this, other, ignore_nested) <= 0; + } + + bool is_same_position(const cursor &other, bool ignore_nested = false) const { + return compare_position(*this, other, ignore_nested) == 0; + } + + bool is_after_than(const cursor &other, bool ignore_nested = false) const { + return compare_position(*this, other, ignore_nested) > 0; + } + + bool is_same_or_after_than(const cursor &other, + bool ignore_nested = false) const { + return compare_position(*this, other, ignore_nested) >= 0; + } + /// \brief Returns the application context associated with the cursor. inline void *get_context() const noexcept; @@ -6192,6 +6221,21 @@ MDBX_CXX11_CONSTEXPR bool operator!=(const cursor &a, return a.handle_ != b.handle_; } +inline int compare_position_nothrow(const cursor &left, const cursor &right, + bool ignore_nested = false) noexcept { + return mdbx_cursor_compare(left.handle_, right.handle_, ignore_nested); +} + +inline int compare_position(const cursor &left, const cursor &right, + bool ignore_nested = false) { + const auto diff = compare_position_nothrow(left, right, ignore_nested); + assert(compare_position_nothrow(right, left, ignore_nested) == -diff); + if (MDBX_LIKELY(int16_t(diff) == diff)) + MDBX_CXX20_LIKELY + return int(diff); + throw_incomparable_cursors(); +} + inline cursor::move_result::move_result(const cursor &cursor, bool throw_notfound) : pair_result(slice(), slice(), false) { diff --git a/src/mdbx.c++ b/src/mdbx.c++ index dd75aaa0..4381b8e8 100644 --- a/src/mdbx.c++ +++ b/src/mdbx.c++ @@ -233,6 +233,11 @@ namespace mdbx { "into an incompatible memory allocation scheme."); } +[[noreturn]] __cold void throw_incomparable_cursors() { + throw std::logic_error( + "mdbx:: incomparable and/or invalid cursors to compare positions."); +} + [[noreturn]] __cold void throw_bad_value_size() { throw bad_value_size(MDBX_BAD_VALSIZE); }