Skip to content

Commit

Permalink
Merge pull request #15176 from Habbie/lmdb-prefix-lookup
Browse files Browse the repository at this point in the history
lmdb-safe: add prefix() cursor; use it in list/lookup/get
  • Loading branch information
Habbie authored Feb 28, 2025
2 parents 90dfa3d + e8c23ea commit 3223190
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 12 deletions.
36 changes: 36 additions & 0 deletions ext/lmdb-safe/lmdb-safe.hh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <mutex>
#include <vector>
#include <algorithm>
#include <string>
#include <string_view>
#include <atomic>
#include <arpa/inet.h>

Expand All @@ -23,6 +25,13 @@
#endif

using std::string_view;
using std::string;

#if BOOST_VERSION >= 106100
#define StringView string_view
#else
#define StringView string
#endif

/* open issues:
*
Expand Down Expand Up @@ -328,6 +337,9 @@ public:
return ret;
}

template <class T>
T get() const;

operator MDB_val&()
{
return d_mdbval;
Expand All @@ -344,6 +356,12 @@ private:
#endif
};

template <>
inline std::string MDBInVal::get<std::string>() const
{
return {static_cast<char*>(d_mdbval.mv_data), d_mdbval.mv_size};
}

class MDBROCursor;

class MDBROTransactionImpl
Expand Down Expand Up @@ -447,6 +465,7 @@ class MDBGenCursor
private:
std::vector<T*> *d_registry;
MDB_cursor* d_cursor{nullptr};
std::string d_prefix{""};
public:
MDB_txn* d_txn{nullptr}; // ew, public
uint64_t d_txtime{0};
Expand Down Expand Up @@ -555,6 +574,9 @@ private:

while (true) {
auto sval = data.getNoStripHeader<std::string_view>();
if (d_prefix.length() > 0 && key.getNoStripHeader<StringView>().rfind(d_prefix, 0) != 0) {
return MDB_NOTFOUND;
}

if (!LMDBLS::LSisDeleted(sval)) {
// done!
Expand Down Expand Up @@ -608,6 +630,7 @@ private:
public:
int get(MDBOutVal& key, MDBOutVal& data, MDB_cursor_op op)
{
d_prefix.clear();
int rc = mdb_cursor_get(d_cursor, &key.d_mdbval, &data.d_mdbval, op);
if(rc && rc != MDB_NOTFOUND)
throw std::runtime_error("Unable to get from cursor: " + std::string(mdb_strerror(rc)));
Expand All @@ -616,14 +639,27 @@ public:

int find(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
{
d_prefix.clear();
key.d_mdbval = in.d_mdbval;
int rc=mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), &data.d_mdbval, MDB_SET);
if(rc && rc != MDB_NOTFOUND)
throw std::runtime_error("Unable to find from cursor: " + std::string(mdb_strerror(rc)));
return skipDeleted(key, data, MDB_SET, rc);
}

int prefix(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
{
d_prefix = in.get<string>();
return _lower_bound(in, key, data);
}

int lower_bound(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
{
d_prefix.clear();
return _lower_bound(in, key, data);
}

int _lower_bound(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data) // used by prefix() and lower_bound()
{
key.d_mdbval = in.d_mdbval;

Expand Down
19 changes: 7 additions & 12 deletions modules/lmdbbackend/lmdbbackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1468,10 +1468,7 @@ bool LMDBBackend::list(const DNSName& target, int /* id */, bool include_disable
d_matchkey = co(di.id);

MDBOutVal key, val;
auto a = d_getcursor->lower_bound(d_matchkey, key, val);
auto b0 = key.getNoStripHeader<StringView>();
auto b = b0.rfind(d_matchkey, 0);
if (a || b != 0) {
if (d_getcursor->prefix(d_matchkey, key, val) != 0) {
d_getcursor.reset();
}

Expand Down Expand Up @@ -1534,7 +1531,7 @@ void LMDBBackend::lookup(const QType& type, const DNSName& qdomain, int zoneId,
d_matchkey = co(zoneId, relqname, type.getCode());
}

if (d_getcursor->lower_bound(d_matchkey, key, val) || key.getNoStripHeader<StringView>().rfind(d_matchkey, 0) != 0) {
if (d_getcursor->prefix(d_matchkey, key, val) != 0) {
d_getcursor.reset();
if (d_dolog) {
g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us to execute (found nothing)" << endl;
Expand Down Expand Up @@ -1572,7 +1569,7 @@ bool LMDBBackend::get(DNSZoneRecord& zr)

if (zr.dr.d_type == QType::NSEC3) {
// Hit a magic NSEC3 skipping
if (d_getcursor->next(d_currentKey, d_currentVal) || d_currentKey.getNoStripHeader<StringView>().rfind(d_matchkey, 0) != 0) {
if (d_getcursor->next(d_currentKey, d_currentVal) != 0) {
// cerr<<"resetting d_getcursor 1"<<endl;
d_getcursor.reset();
}
Expand Down Expand Up @@ -1600,7 +1597,7 @@ bool LMDBBackend::get(DNSZoneRecord& zr)

if (d_currentrrsetpos >= d_currentrrset.size()) {
d_currentrrset.clear(); // will invalidate lrr
if (d_getcursor->next(d_currentKey, d_currentVal) || d_currentKey.getNoStripHeader<StringView>().rfind(d_matchkey, 0) != 0) {
if (d_getcursor->next(d_currentKey, d_currentVal) != 0) {
// cerr<<"resetting d_getcursor 2"<<endl;
d_getcursor.reset();
}
Expand Down Expand Up @@ -2487,15 +2484,15 @@ bool LMDBBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName

auto cursor = txn->txn->getCursor(txn->db->dbi);
MDBOutVal key, val;
if (cursor.lower_bound(matchkey, key, val)) {
if (cursor.prefix(matchkey, key, val) != 0) {
// cout << "Could not find anything"<<endl;
return false;
}

bool hasOrderName = !ordername.empty();
bool needNSEC3 = hasOrderName;

for (; key.getNoStripHeader<StringView>().rfind(matchkey, 0) == 0;) {
do {
vector<LMDBResourceRecord> lrrs;

if (co.getQType(key.getNoStripHeader<StringView>()) != QType::NSEC3) {
Expand All @@ -2521,9 +2518,7 @@ bool LMDBBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName
}
}

if (cursor.next(key, val))
break;
}
} while (cursor.next(key, val) == 0);

bool del = false;
LMDBResourceRecord lrr;
Expand Down

0 comments on commit 3223190

Please sign in to comment.