From 1d8242cd7f4e4235c6a2aeb43574121dce2122c8 Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Fri, 21 Mar 2025 12:00:56 +0100 Subject: [PATCH] Handle marked-as-deleted elements in ReadonlyOperations::get<> --- ext/lmdb-safe/lmdb-typed.hh | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index 5e48ff161c..4cdcb4efaf 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -275,15 +275,19 @@ public: // } //! Get item with id, from main table directly - bool get(uint32_t itemId, T& value) + int get2(uint32_t itemId, T& value) { MDBOutVal data{}; - if((*d_parent.d_txn)->get(d_parent.d_parent->d_main, itemId, data)) { - return false; + int rc; + rc = (*d_parent.d_txn)->get(d_parent.d_parent->d_main, itemId, data); + if (rc == 0) { + deserializeFromBuffer(data.get(), value); } - - deserializeFromBuffer(data.get(), value); - return true; + return rc; + } + bool get(uint32_t itemId, T& value) + { + return get2(itemId, value) == 0; } //! Get item through index N, then via the main database @@ -301,17 +305,24 @@ public: // because we know we only want one item, pass onlyOldest=true to consistently get the same one out of a set of duplicates get_multi(key, ids, true); - if (ids.size() == 0) { + switch (ids.size()) { + case 0: return 0; - } - - if (ids.size() == 1) { - if (get(ids[0], out)) { + case 1: { + auto rc = get2(ids[0], out); + if (rc == 0) { return ids[0]; } + if (rc == MDB_NOTFOUND) { + /* element not present, or has been marked deleted */ + return 0; + } + throw std::runtime_error("in index get, failed (" + std::to_string(rc) + ")"); + break; + } + default: + throw std::runtime_error("in index get, found more than one item"); } - - throw std::runtime_error("in index get, found more than one item"); } // //! Cardinality of index N -- 2.47.2