diff --git a/olc_art.cpp b/olc_art.cpp index 3b6f8bd5..09eda278 100644 --- a/olc_art.cpp +++ b/olc_art.cpp @@ -1,4 +1,4 @@ -// Copyright 2019-2024 Laurynas Biveinis +// Copyright 2019-2025 UnoDB contributors // // CAUTION: [global.hpp] MUST BE THE FIRST INCLUDE IN ALL SOURCE AND @@ -94,9 +94,10 @@ using db_inode_qsbr_deleter_parent = // // @return the outcome of that computation and false if the // read_critical_section could not be unlocked. -inline bool UNLOCK(unodb::optimistic_lock::read_critical_section &cs, - bool ret) { - return (!cs.try_read_unlock()) ? false : ret; +[[nodiscard]] inline bool unlock_and_return( + const unodb::optimistic_lock::read_critical_section &cs, + bool ret) noexcept { + return UNODB_DETAIL_LIKELY(cs.try_read_unlock()) ? ret : false; } } // namespace @@ -1718,12 +1719,13 @@ bool olc_db::iterator::try_seek(detail::art_key search_key, bool &match, if (cmp_ < 0) { // FWD and the search key is ordered before this node. We // want the left-most leaf under the node. - return UNLOCK(node_critical_section, - try_left_most_traversal(node, parent_critical_section)); + return unlock_and_return( + node_critical_section, + try_left_most_traversal(node, parent_critical_section)); } // FWD and the search key is ordered after this node. Right // most descent and then next(). - return UNLOCK( + return unlock_and_return( node_critical_section, try_right_most_traversal(node, parent_critical_section)) && try_next(); @@ -1732,13 +1734,15 @@ bool olc_db::iterator::try_seek(detail::art_key search_key, bool &match, if (cmp_ < 0) { // REV and the search key is ordered before this node. We // want the preceeding key. - return UNLOCK(node_critical_section, - try_left_most_traversal(node, parent_critical_section)) && + return unlock_and_return( + node_critical_section, + try_left_most_traversal(node, parent_critical_section)) && try_prior(); } // REV and the search key is ordered after this node. - return UNLOCK(node_critical_section, - try_right_most_traversal(node, parent_critical_section)); + return unlock_and_return( + node_critical_section, + try_right_most_traversal(node, parent_critical_section)); } remaining_key.shift_right(key_prefix_length); auto res = inode->find_child(node_type, remaining_key[0]); diff --git a/optimistic_lock.hpp b/optimistic_lock.hpp index b2b74474..8935dcb8 100644 --- a/optimistic_lock.hpp +++ b/optimistic_lock.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023 Laurynas Biveinis +// Copyright (C) 2019-2025 UnoDB contributors #ifndef UNODB_DETAIL_OPTIMISTIC_LOCK_HPP #define UNODB_DETAIL_OPTIMISTIC_LOCK_HPP @@ -242,7 +242,7 @@ class [[nodiscard]] optimistic_lock final { // the version that was used to construct this // read_critical_section. [[nodiscard, gnu::flatten]] UNODB_DETAIL_FORCE_INLINE bool try_read_unlock() - UNODB_DETAIL_RELEASE_CONST noexcept { + const noexcept { const auto result = lock->try_read_unlock(version); #ifndef NDEBUG lock = nullptr; @@ -269,7 +269,7 @@ class [[nodiscard]] optimistic_lock final { // // @return true if the version is unchanged and false if the // caller MUST restart because the version has been changed. - [[nodiscard]] bool check() UNODB_DETAIL_RELEASE_CONST noexcept { + [[nodiscard]] bool check() const noexcept { const auto result = lock->check(version); #ifndef NDEBUG if (UNODB_DETAIL_UNLIKELY(!result)) lock = nullptr; // LCOV_EXCL_LINE @@ -307,7 +307,11 @@ class [[nodiscard]] optimistic_lock final { read_critical_section &operator=(const read_critical_section &) = delete; private: - optimistic_lock *lock{nullptr}; +#ifndef NDEBUG + mutable +#endif + optimistic_lock *lock{nullptr}; + version_type version{0}; friend class write_guard;