Skip to content

Commit 86083a2

Browse files
committed
fixes lmdbjava#72 - closedBackward doesn't work when the start value is greater than the last key
1 parent e6e71b4 commit 86083a2

File tree

4 files changed

+25
-10
lines changed

4 files changed

+25
-10
lines changed

src/main/java/org/lmdbjava/CursorIterator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ private void executeCursorOp(final CursorOp op) {
113113
case GET_START_KEY:
114114
found = cursor.get(range.getStart(), MDB_SET_RANGE);
115115
break;
116+
case GET_START_KEY_BACKWARD:
117+
found = cursor.get(range.getStart(), MDB_SET_RANGE) || cursor.last();
118+
break;
116119
default:
117120
throw new IllegalStateException("Unknown cursor operation");
118121
}

src/main/java/org/lmdbjava/KeyRangeType.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,12 @@
2222

2323
import java.util.Comparator;
2424
import static java.util.Objects.requireNonNull;
25-
import static org.lmdbjava.KeyRangeType.BACKWARD_ALL;
2625
import static org.lmdbjava.KeyRangeType.CursorOp.FIRST;
2726
import static org.lmdbjava.KeyRangeType.CursorOp.GET_START_KEY;
27+
import static org.lmdbjava.KeyRangeType.CursorOp.GET_START_KEY_BACKWARD;
2828
import static org.lmdbjava.KeyRangeType.CursorOp.LAST;
2929
import static org.lmdbjava.KeyRangeType.CursorOp.NEXT;
3030
import static org.lmdbjava.KeyRangeType.CursorOp.PREV;
31-
import static org.lmdbjava.KeyRangeType.FORWARD_ALL;
3231
import static org.lmdbjava.KeyRangeType.IteratorOp.CALL_NEXT_OP;
3332
import static org.lmdbjava.KeyRangeType.IteratorOp.RELEASE;
3433
import static org.lmdbjava.KeyRangeType.IteratorOp.TERMINATE;
@@ -340,21 +339,21 @@ CursorOp initialOp() {
340339
case BACKWARD_ALL:
341340
return LAST;
342341
case BACKWARD_AT_LEAST:
343-
return GET_START_KEY;
342+
return GET_START_KEY_BACKWARD;
344343
case BACKWARD_AT_MOST:
345344
return LAST;
346345
case BACKWARD_CLOSED:
347-
return GET_START_KEY;
346+
return GET_START_KEY_BACKWARD;
348347
case BACKWARD_CLOSED_OPEN:
349-
return GET_START_KEY;
348+
return GET_START_KEY_BACKWARD;
350349
case BACKWARD_GREATER_THAN:
351-
return GET_START_KEY;
350+
return GET_START_KEY_BACKWARD;
352351
case BACKWARD_LESS_THAN:
353352
return LAST;
354353
case BACKWARD_OPEN:
355-
return GET_START_KEY;
354+
return GET_START_KEY_BACKWARD;
356355
case BACKWARD_OPEN_CLOSED:
357-
return GET_START_KEY;
356+
return GET_START_KEY_BACKWARD;
358357
default:
359358
throw new IllegalStateException("Invalid type");
360359
}
@@ -486,6 +485,10 @@ enum CursorOp {
486485
* Get "start" key with {@link GetOp#MDB_SET_RANGE}.
487486
*/
488487
GET_START_KEY,
488+
/**
489+
* Get "start" key with {@link GetOp#MDB_SET_RANGE}, fall back to LAST.
490+
*/
491+
GET_START_KEY_BACKWARD,
489492
/**
490493
* Move forward.
491494
*/

src/test/java/org/lmdbjava/CursorIteratorTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.NoSuchElementException;
3434
import static org.hamcrest.CoreMatchers.is;
3535
import static org.hamcrest.MatcherAssert.assertThat;
36+
import static org.hamcrest.Matchers.hasSize;
3637
import org.junit.After;
3738
import org.junit.Before;
3839
import org.junit.Rule;
@@ -163,6 +164,7 @@ public void before() throws IOException {
163164
public void closedBackwardTest() {
164165
verify(closedBackward(bb(7), bb(3)), 6, 4);
165166
verify(closedBackward(bb(6), bb(2)), 6, 4, 2);
167+
verify(closedBackward(bb(9), bb(3)), 8, 6, 4);
166168
}
167169

168170
@Test
@@ -181,6 +183,7 @@ public void closedOpenTest() {
181183
public void closedTest() {
182184
verify(closed(bb(3), bb(7)), 4, 6);
183185
verify(closed(bb(2), bb(6)), 2, 4, 6);
186+
verify(closed(bb(1), bb(7)), 2, 4, 6);
184187
}
185188

186189
@Test
@@ -327,7 +330,7 @@ private void verify(final KeyRange<ByteBuffer> range,
327330
}
328331
}
329332

330-
assertThat(results.size(), is(expected.length));
333+
assertThat(results, hasSize(expected.length));
331334
for (int idx = 0; idx < results.size(); idx++) {
332335
assertThat(results.get(idx), is(expected[idx]));
333336
}

src/test/java/org/lmdbjava/KeyRangeTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import static org.lmdbjava.KeyRange.openClosed;
4747
import static org.lmdbjava.KeyRange.openClosedBackward;
4848
import org.lmdbjava.KeyRangeType.CursorOp;
49-
import static org.lmdbjava.KeyRangeType.CursorOp.FIRST;
5049
import org.lmdbjava.KeyRangeType.IteratorOp;
5150
import static org.lmdbjava.KeyRangeType.IteratorOp.TERMINATE;
5251

@@ -233,6 +232,7 @@ private static class FakeCursor {
233232

234233
@SuppressWarnings("checkstyle:ReturnCount")
235234
Integer apply(final CursorOp op, final Integer startKey) {
235+
final Integer key;
236236
switch (op) {
237237
case FIRST:
238238
return first();
@@ -244,6 +244,12 @@ Integer apply(final CursorOp op, final Integer startKey) {
244244
return prev();
245245
case GET_START_KEY:
246246
return getWithSetRange(startKey);
247+
case GET_START_KEY_BACKWARD:
248+
key = getWithSetRange(startKey);
249+
if (key != null) {
250+
return key;
251+
}
252+
return last();
247253
default:
248254
throw new IllegalStateException("Unknown operation");
249255
}

0 commit comments

Comments
 (0)