Skip to content

Commit

Permalink
Fix for doing reverse range query, #69
Browse files Browse the repository at this point in the history
  • Loading branch information
kriszyp committed Jul 7, 2021
1 parent 3bbbe7a commit 1dd351d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 21 deletions.
35 changes: 14 additions & 21 deletions src/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ int CursorWrap::returnEntry(int lastRC, MDB_val &key, MDB_val &data) {
comparison = mdb_dcmp(tw->txn, dw->dbi, &endKey, &data);
else
comparison = mdb_cmp(tw->txn, dw->dbi, &endKey, &key);
if ((flags & 0x400) ? comparison >= 0 : (comparison <=0)) {
if ((flags & 0x400) ? comparison >= 0 : (comparison <= 0)) {
return 0;
}
}
Expand Down Expand Up @@ -438,34 +438,27 @@ uint32_t CursorWrap::doPosition(uint32_t offset, uint32_t keySize, uint64_t endK
data.mv_size = endKeyAddress ? *((uint32_t*)startValueBuffer) : 0;
data.mv_data = startValueBuffer + 1;
rc = mdb_cursor_get(cursor, &key, &data, data.mv_size ? MDB_GET_BOTH_RANGE : MDB_SET_KEY);
if (rc == MDB_NOTFOUND)
return 0;
if (flags & 0x1000 && !endKeyAddress) {
if (rc == MDB_NOTFOUND)
return 0;
size_t count;
rc = mdb_cursor_count(cursor, &count);
if (rc)
throwLmdbError(rc);
return count;
}
} else
rc = mdb_cursor_get(cursor, &key, &data, MDB_SET_RANGE);
if (flags & 0x400) {// reverse
MDB_val firstKey = key; // save it for comparison
if (rc) { // not found
if (flags & 0x800) {// only values for this key
// nothing to do, not found
} else if (true) {// MDB_SET_RANGE, not found, go to end
if (flags & 0x400) // reverse, get last dup
rc = mdb_cursor_get(cursor, &key, &data, MDB_LAST_DUP);
} else {
if (flags & 0x400) {// reverse
MDB_val firstKey = key; // save it for comparison
rc = mdb_cursor_get(cursor, &key, &data, MDB_SET_RANGE);
if (rc)
rc = mdb_cursor_get(cursor, &key, &data, MDB_LAST);
}
} else {
if (flags & 0x800) {// only values for this key
// compare data
rc = mdb_cursor_get(cursor, &key, &data, MDB_LAST_DUP);
} else {// MDB_SET_RANGE
if (mdb_cmp(tw->txn, dw->dbi, &firstKey, &key))
rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV);
}
}
if (mdb_cmp(tw->txn, dw->dbi, &firstKey, &key) && !rc)
rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV);
} else // forward, just do a get by range
rc = mdb_cursor_get(cursor, &key, &data, MDB_SET_RANGE);
}
}
while (offset-- > 0 && !rc) {
Expand Down
26 changes: 26 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,32 @@ describe('lmdb-store', function() {
value.should.equal(db.get(key))
}
keys.should.deep.equal(returnedKeys)

returnedKeys = []
for (let { key, value } of db.getRange({
reverse: true,
})) {
returnedKeys.unshift(key)
value.should.equal(db.get(key))
}
keys.should.deep.equal(returnedKeys)
});
it('reverse query range', async function() {
const keys = [
[ 'Test', 100, 1 ],
[ 'Test', 10010, 2 ],
[ 'Test', 10010, 3 ],
]
for (let key of keys)
await db.put(key, 3);
let returnedKeys = []
for (let { key, value } of db.getRange({
start: ['Test', null],
end: ['Test', null],
reverse: true
})) {
throw new Error('Should not return any results')
}
});
it('string', async function() {
await db.put('key1', 'Hello world!');
Expand Down

0 comments on commit 1dd351d

Please sign in to comment.