diff options
author | Minijackson <minijackson@riseup.net> | 2018-05-23 17:20:34 +0200 |
---|---|---|
committer | Minijackson <minijackson@riseup.net> | 2018-05-23 17:25:18 +0200 |
commit | 427b1d38d870e6876e10349b1081b56ff3390dec (patch) | |
tree | 8895888f5e4900ab8b41e500df32a89dda477e1c /common/storage_lmdb.cpp | |
parent | 426392f71d5f45aad8c57969643fd6c365ce2362 (diff) | |
download | sink-427b1d38d870e6876e10349b1081b56ff3390dec.tar.gz sink-427b1d38d870e6876e10349b1081b56ff3390dec.zip |
Add and test findAllInRange for ranged lookups
Diffstat (limited to 'common/storage_lmdb.cpp')
-rw-r--r-- | common/storage_lmdb.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp index 5fb1d0f..bd9bdce 100644 --- a/common/storage_lmdb.cpp +++ b/common/storage_lmdb.cpp | |||
@@ -558,6 +558,68 @@ void DataStore::NamedDatabase::findLatest(const QByteArray &k, const std::functi | |||
558 | return; | 558 | return; |
559 | } | 559 | } |
560 | 560 | ||
561 | int DataStore::NamedDatabase::findAllInRange(const QByteArray &lowerBound, const QByteArray &upperBound, | ||
562 | const std::function<void(const QByteArray &key, const QByteArray &value)> &resultHandler, | ||
563 | const std::function<void(const DataStore::Error &error)> &errorHandler) const | ||
564 | { | ||
565 | if (!d || !d->transaction) { | ||
566 | // Not an error. We rely on this to read nothing from non-existing databases. | ||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | MDB_cursor *cursor; | ||
571 | if (int rc = mdb_cursor_open(d->transaction, d->dbi, &cursor)) { | ||
572 | // Invalid arguments can mean that the transaction doesn't contain the db dbi | ||
573 | Error error(d->name.toLatin1() + d->db, getErrorCode(rc), | ||
574 | QByteArray("Error during mdb_cursor_open: ") + QByteArray(mdb_strerror(rc)) + | ||
575 | ". Lower bound: " + lowerBound + " Upper bound: " + upperBound); | ||
576 | errorHandler ? errorHandler(error) : d->defaultErrorHandler(error); | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | int numberOfRetrievedValues = 0; | ||
581 | |||
582 | MDB_val firstKey = { .mv_size = (size_t)lowerBound.size(), .mv_data = (void *)lowerBound.constData() }, | ||
583 | idealLastKey = { .mv_size = (size_t)upperBound.size(), .mv_data = (void *)upperBound.constData() }, | ||
584 | lastKey = idealLastKey, currentKey; | ||
585 | MDB_val reference; | ||
586 | |||
587 | // Find the last key past the range | ||
588 | int rc = mdb_cursor_get(cursor, &lastKey, &reference, MDB_SET_RANGE); | ||
589 | |||
590 | // If only equal, move forward one spot | ||
591 | if (rc == MDB_SUCCESS && mdb_cmp(d->transaction, d->dbi, &lastKey, &idealLastKey) == 0) { | ||
592 | rc = mdb_cursor_get(cursor, &lastKey, &reference, MDB_NEXT); | ||
593 | } | ||
594 | |||
595 | bool untilEnd = false; | ||
596 | if (rc != MDB_SUCCESS) { | ||
597 | // Nothing is greater than the upper bound, meaning search until the end | ||
598 | untilEnd = true; | ||
599 | } | ||
600 | |||
601 | // Find the first key in the range | ||
602 | rc = mdb_cursor_get(cursor, &firstKey, &reference, MDB_SET_RANGE); | ||
603 | |||
604 | if (rc != MDB_SUCCESS) { | ||
605 | // Nothing is greater or equal than the lower bound, meaning no result | ||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | currentKey = firstKey; | ||
610 | |||
611 | do { | ||
612 | // If we have a stopping point and this is the stopping point | ||
613 | if (!untilEnd && mdb_cmp(d->transaction, d->dbi, ¤tKey, &lastKey) == 0) { | ||
614 | break; | ||
615 | } | ||
616 | |||
617 | const auto currentBAKey = QByteArray::fromRawData((char *)currentKey.mv_data, currentKey.mv_size); | ||
618 | const auto currentBAValue = QByteArray::fromRawData((char *)reference.mv_data, reference.mv_size); | ||
619 | resultHandler(currentBAKey, currentBAValue); | ||
620 | } while (mdb_cursor_get(cursor, ¤tKey, &reference, MDB_NEXT) == MDB_SUCCESS); | ||
621 | } | ||
622 | |||
561 | qint64 DataStore::NamedDatabase::getSize() | 623 | qint64 DataStore::NamedDatabase::getSize() |
562 | { | 624 | { |
563 | if (!d || !d->transaction) { | 625 | if (!d || !d->transaction) { |