From: Miod Vallat Date: Fri, 21 Mar 2025 11:00:56 +0000 (+0100) Subject: Handle marked-as-deleted elements in ReadonlyOperations::get<> X-Git-Tag: dnsdist-2.0.0-alpha2~127^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F15339%2Fhead;p=thirdparty%2Fpdns.git Handle marked-as-deleted elements in ReadonlyOperations::get<> --- 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