Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

auth-4.9: lmdb-safe: add prefix() cursor; use it in list/lookup/get #15237

Draft
wants to merge 4 commits into
base: rel/auth-4.9.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions ext/lmdb-safe/lmdb-safe.hh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <mutex>
#include <vector>
#include <algorithm>
#include <string>
#include <string_view>

#include "config.h"

Expand All @@ -24,6 +26,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 @@ -300,6 +309,9 @@ public:
return ret;
}

template <class T>
T get() const;

operator MDB_val&()
{
return d_mdbval;
Expand All @@ -312,6 +324,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 @@ -415,6 +433,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 @@ -523,6 +542,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 @@ -573,6 +595,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 @@ -581,14 +604,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 @@ -1405,10 +1405,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 @@ -1470,7 +1467,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 @@ -1508,7 +1505,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 @@ -1536,7 +1533,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 @@ -2423,15 +2420,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 @@ -2456,9 +2453,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
Loading