diff --git a/src/main/java/org/lmdbjava/Dbi.java b/src/main/java/org/lmdbjava/Dbi.java index 05c11a7d..883b7d92 100644 --- a/src/main/java/org/lmdbjava/Dbi.java +++ b/src/main/java/org/lmdbjava/Dbi.java @@ -32,6 +32,10 @@ import static org.lmdbjava.Dbi.KeyExistsException.MDB_KEYEXIST; import static org.lmdbjava.Dbi.KeyNotFoundException.MDB_NOTFOUND; import static org.lmdbjava.Env.SHOULD_CHECK; +import static org.lmdbjava.KeyRange.all; +import static org.lmdbjava.KeyRange.allBackward; +import static org.lmdbjava.KeyRange.atLeast; +import static org.lmdbjava.KeyRange.atLeastBackward; import static org.lmdbjava.Library.LIB; import org.lmdbjava.Library.MDB_stat; import static org.lmdbjava.Library.RUNTIME; @@ -211,7 +215,7 @@ public byte[] getName() { * @return iterator */ public CursorIterator iterate(final Txn txn) { - return iterate(txn, KeyRange.forward()); + return iterate(txn, all()); } /** @@ -227,8 +231,7 @@ public CursorIterator iterate(final Txn txn, final IteratorType type) { if (SHOULD_CHECK) { requireNonNull(type); } - final KeyRange range = type == FORWARD - ? KeyRange.forward() : KeyRange.backward(); + final KeyRange range = type == FORWARD ? all() : allBackward(); return iterate(txn, range); } @@ -251,9 +254,9 @@ public CursorIterator iterate(final Txn txn, final T key, final KeyRange range; if (type == FORWARD) { - range = key == null ? KeyRange.forward() : KeyRange.atLeast(key); + range = key == null ? all() : atLeast(key); } else { - range = key == null ? KeyRange.backward() : KeyRange.atLeastBackward(key); + range = key == null ? allBackward() : atLeastBackward(key); } return iterate(txn, range); diff --git a/src/main/java/org/lmdbjava/KeyRange.java b/src/main/java/org/lmdbjava/KeyRange.java index 0c6bb581..6e2b989d 100644 --- a/src/main/java/org/lmdbjava/KeyRange.java +++ b/src/main/java/org/lmdbjava/KeyRange.java @@ -30,8 +30,8 @@ import static org.lmdbjava.KeyRange.IteratorOp.CALL_NEXT_OP; import static org.lmdbjava.KeyRange.IteratorOp.RELEASE; import static org.lmdbjava.KeyRange.IteratorOp.TERMINATE; -import static org.lmdbjava.KeyRangeType.BACKWARD; -import static org.lmdbjava.KeyRangeType.FORWARD; +import static org.lmdbjava.KeyRangeType.BACKWARD_ALL; +import static org.lmdbjava.KeyRangeType.FORWARD_ALL; /** * Limits the range and direction of keys to iterate. @@ -44,8 +44,8 @@ @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.StdCyclomaticComplexity"}) public final class KeyRange { - private static final KeyRange BACK = new KeyRange<>(BACKWARD, null, null); - private static final KeyRange FORW = new KeyRange<>(FORWARD, null, null); + private static final KeyRange BACK = new KeyRange<>(BACKWARD_ALL, null, null); + private static final KeyRange FORW = new KeyRange<>(FORWARD_ALL, null, null); private final T start; private final T stop; private final KeyRangeType type; @@ -75,91 +75,91 @@ public KeyRange(final KeyRangeType type, final T start, final T stop) { } /** - * Create a {@link KeyRangeType#FORWARD_START} range. + * Create a {@link KeyRangeType#FORWARD_ALL} range. * - * @param buffer type - * @param start start key (required) + * @param buffer type * @return a key range (never null) */ - public static KeyRange atLeast(final T start) { - return new KeyRange<>(KeyRangeType.FORWARD_START, start, null); + public static KeyRange all() { + return FORW; } /** - * Create a {@link KeyRangeType#BACKWARD_START} range. + * Create a {@link KeyRangeType#BACKWARD_ALL} range. * - * @param buffer type - * @param start start key (required) + * @param buffer type * @return a key range (never null) */ - public static KeyRange atLeastBackward(final T start) { - return new KeyRange<>(KeyRangeType.BACKWARD_START, start, null); + public static KeyRange allBackward() { + return BACK; } /** - * Create a {@link KeyRangeType#FORWARD_STOP} range. + * Create a {@link KeyRangeType#FORWARD_AT_LEAST} range. * - * @param buffer type - * @param stop stop key (required) + * @param buffer type + * @param start start key (required) * @return a key range (never null) */ - public static KeyRange atMost(final T stop) { - return new KeyRange<>(KeyRangeType.FORWARD_STOP, null, stop); + public static KeyRange atLeast(final T start) { + return new KeyRange<>(KeyRangeType.FORWARD_AT_LEAST, start, null); } /** - * Create a {@link KeyRangeType#BACKWARD_STOP} range. + * Create a {@link KeyRangeType#BACKWARD_AT_LEAST} range. * - * @param buffer type - * @param stop stop key (required) + * @param buffer type + * @param start start key (required) * @return a key range (never null) */ - public static KeyRange atMostBackward(final T stop) { - return new KeyRange<>(KeyRangeType.BACKWARD_STOP, null, stop); + public static KeyRange atLeastBackward(final T start) { + return new KeyRange<>(KeyRangeType.BACKWARD_AT_LEAST, start, null); } /** - * Create a {@link KeyRangeType#BACKWARD} range. + * Create a {@link KeyRangeType#FORWARD_AT_MOST} range. * - * @param buffer type + * @param buffer type + * @param stop stop key (required) * @return a key range (never null) */ - public static KeyRange backward() { - return BACK; + public static KeyRange atMost(final T stop) { + return new KeyRange<>(KeyRangeType.FORWARD_AT_MOST, null, stop); } /** - * Create a {@link KeyRangeType#FORWARD} range. + * Create a {@link KeyRangeType#BACKWARD_AT_MOST} range. * - * @param buffer type + * @param buffer type + * @param stop stop key (required) * @return a key range (never null) */ - public static KeyRange forward() { - return FORW; + public static KeyRange atMostBackward(final T stop) { + return new KeyRange<>(KeyRangeType.BACKWARD_AT_MOST, null, stop); } /** - * Create a {@link KeyRangeType#FORWARD_RANGE} range. + * Create a {@link KeyRangeType#FORWARD_CLOSED} range. * * @param buffer type * @param start start key (required) * @param stop stop key (required) * @return a key range (never null) */ - public static KeyRange range(final T start, final T stop) { - return new KeyRange<>(KeyRangeType.FORWARD_RANGE, start, stop); + public static KeyRange closed(final T start, final T stop) { + return new KeyRange<>(KeyRangeType.FORWARD_CLOSED, start, stop); } /** - * Create a {@link KeyRangeType#BACKWARD_RANGE} range. + * Create a {@link KeyRangeType#BACKWARD_CLOSED} range. * * @param buffer type * @param start start key (required) * @param stop stop key (required) * @return a key range (never null) */ - public static KeyRange rangeBackward(final T start, final T stop) { - return new KeyRange<>(KeyRangeType.BACKWARD_RANGE, start, stop); + public static KeyRange closedBackward(final T start, final T stop) { + return new KeyRange<>(KeyRangeType.BACKWARD_CLOSED, start, stop); } /** @@ -201,21 +201,21 @@ public KeyRangeType getType() { @SuppressWarnings("checkstyle:ReturnCount") CursorOp initialOp() { switch (type) { - case FORWARD: + case FORWARD_ALL: return FIRST; - case FORWARD_START: + case FORWARD_AT_LEAST: return GET_START_KEY; - case FORWARD_STOP: + case FORWARD_AT_MOST: return FIRST; - case FORWARD_RANGE: + case FORWARD_CLOSED: return GET_START_KEY; - case BACKWARD: + case BACKWARD_ALL: return LAST; - case BACKWARD_START: + case BACKWARD_AT_LEAST: return GET_START_KEY; - case BACKWARD_STOP: + case BACKWARD_AT_MOST: return LAST; - case BACKWARD_RANGE: + case BACKWARD_CLOSED: return GET_START_KEY; default: throw new IllegalStateException("Invalid type"); @@ -238,21 +238,21 @@ > IteratorOp iteratorOp(final C c, return TERMINATE; } switch (type) { - case FORWARD: + case FORWARD_ALL: return RELEASE; - case FORWARD_START: + case FORWARD_AT_LEAST: return RELEASE; - case FORWARD_STOP: + case FORWARD_AT_MOST: return c.compare(buffer, stop) > 0 ? TERMINATE : RELEASE; - case FORWARD_RANGE: + case FORWARD_CLOSED: return c.compare(buffer, stop) > 0 ? TERMINATE : RELEASE; - case BACKWARD: + case BACKWARD_ALL: return RELEASE; - case BACKWARD_START: + case BACKWARD_AT_LEAST: return c.compare(buffer, start) > 0 ? CALL_NEXT_OP : RELEASE; // rewind - case BACKWARD_STOP: + case BACKWARD_AT_MOST: return c.compare(buffer, stop) >= 0 ? RELEASE : TERMINATE; - case BACKWARD_RANGE: + case BACKWARD_CLOSED: if (c.compare(buffer, start) > 0) { return CALL_NEXT_OP; // rewind } diff --git a/src/main/java/org/lmdbjava/KeyRangeType.java b/src/main/java/org/lmdbjava/KeyRangeType.java index f84c84c6..9ddbd915 100644 --- a/src/main/java/org/lmdbjava/KeyRangeType.java +++ b/src/main/java/org/lmdbjava/KeyRangeType.java @@ -24,6 +24,12 @@ * Key range type. * *

+ * The terminology used in this class is adapted from Google Guava's ranges. + * Refer to the + * Ranges Explained wiki page for more information. LmddJava prepends either + * "FORWARD" or "BACKWARD" to denote the iterator order. + * + *

* In the examples below, it is assumed the table has keys 2, 4, 6 and 8. */ public enum KeyRangeType { @@ -37,7 +43,7 @@ public enum KeyRangeType { *

* In our example, the returned keys would be 2, 4, 6 and 8. */ - FORWARD(true, false, false), + FORWARD_ALL(true, false, false), /** * Start on the passed key (or the first key immediately after it) and * iterate forward until no keys remain. @@ -49,7 +55,7 @@ public enum KeyRangeType { * In our example and with a passed search key of 5, the returned keys would * be 6 and 8. With a passed key of 6, the returned keys would be 6 and 8. */ - FORWARD_START(true, true, false), + FORWARD_AT_LEAST(true, true, false), /** * Start on the first key and iterate forward until a key equal to it (or the * first key immediately after it) is reached. @@ -61,7 +67,7 @@ public enum KeyRangeType { * In our example and with a passed search key of 5, the returned keys would * be 2 and 4. With a passed key of 6, the returned keys would be 2, 4 and 6. */ - FORWARD_STOP(true, false, true), + FORWARD_AT_MOST(true, false, true), /** * Iterate forward between the passed keys, matching on the first keys * directly equal to the passed key (or immediately following it in the case @@ -75,7 +81,7 @@ public enum KeyRangeType { * In our example and with a passed search range of 3 - 7, the returned keys * would be 4 and 6. With a range of 2 - 6, the keys would be 2, 4 and 6. */ - FORWARD_RANGE(true, true, true), + FORWARD_CLOSED(true, true, true), /** * Start on the last key and iterate backward until no keys remain. * @@ -85,7 +91,7 @@ public enum KeyRangeType { *

* In our example, the returned keys would be 8, 6, 4 and 2. */ - BACKWARD(false, false, false), + BACKWARD_ALL(false, false, false), /** * Start on the passed key (or the first key immediately preceding it) and * iterate backward until no keys remain. @@ -97,7 +103,7 @@ public enum KeyRangeType { * In our example and with a passed search key of 5, the returned keys would * be 4 and 2. With a passed key of 6, the returned keys would be 6, 4 and 2. */ - BACKWARD_START(false, true, false), + BACKWARD_AT_LEAST(false, true, false), /** * Start on the last key and iterate backward until a key equal to it (or the * first key immediately preceding it it) is reached. @@ -109,7 +115,7 @@ public enum KeyRangeType { * In our example and with a passed search key of 5, the returned keys would * be 8 and 6. With a passed key of 6, the returned keys would be 8 and 6. */ - BACKWARD_STOP(false, false, true), + BACKWARD_AT_MOST(false, false, true), /** * Iterate backward between the passed keys, matching on the first keys * directly equal to the passed key (or immediately preceding it in the case @@ -123,7 +129,7 @@ public enum KeyRangeType { * In our example and with a passed search range of 7 - 3, the returned keys * would be 6 and 4. With a range of 6 - 2, the keys would be 6, 4 and 2. */ - BACKWARD_RANGE(false, true, true); + BACKWARD_CLOSED(false, true, true); private final boolean directionForward; private final boolean startKeyRequired; diff --git a/src/test/java/org/lmdbjava/CursorIteratorTest.java b/src/test/java/org/lmdbjava/CursorIteratorTest.java index 745667d8..32227a6f 100644 --- a/src/test/java/org/lmdbjava/CursorIteratorTest.java +++ b/src/test/java/org/lmdbjava/CursorIteratorTest.java @@ -42,14 +42,14 @@ import static org.lmdbjava.DbiFlags.MDB_CREATE; import static org.lmdbjava.Env.open; import static org.lmdbjava.EnvFlags.MDB_NOSUBDIR; +import static org.lmdbjava.KeyRange.all; +import static org.lmdbjava.KeyRange.allBackward; import static org.lmdbjava.KeyRange.atLeast; import static org.lmdbjava.KeyRange.atLeastBackward; import static org.lmdbjava.KeyRange.atMost; import static org.lmdbjava.KeyRange.atMostBackward; -import static org.lmdbjava.KeyRange.backward; -import static org.lmdbjava.KeyRange.forward; -import static org.lmdbjava.KeyRange.range; -import static org.lmdbjava.KeyRange.rangeBackward; +import static org.lmdbjava.KeyRange.closed; +import static org.lmdbjava.KeyRange.closedBackward; import static org.lmdbjava.PutFlags.MDB_NOOVERWRITE; import static org.lmdbjava.TestUtils.DB_1; import static org.lmdbjava.TestUtils.bb; @@ -70,6 +70,40 @@ public void after() { env.close(); } + @Test + public void allBackwardTest() { + verify(allBackward(), 8, 6, 4, 2); + } + + @Test + public void allTest() { + verify(all(), 2, 4, 6, 8); + } + + @Test + public void atLeastBackwardTest() { + verify(atLeastBackward(bb(5)), 4, 2); + verify(atLeastBackward(bb(6)), 6, 4, 2); + } + + @Test + public void atLeastTest() { + verify(atLeast(bb(5)), 6, 8); + verify(atLeast(bb(6)), 6, 8); + } + + @Test + public void atMostBackwardTest() { + verify(atMostBackward(bb(5)), 8, 6); + verify(atMostBackward(bb(6)), 8, 6); + } + + @Test + public void atMostTest() { + verify(atMost(bb(5)), 2, 4); + verify(atMost(bb(6)), 2, 4, 6); + } + @Test public void backwardDeprecated() { try (Txn txn = env.txnRead(); @@ -82,12 +116,6 @@ public void backwardDeprecated() { } } - @Test - public void backwardRange() { - verify(rangeBackward(bb(7), bb(3)), 6, 4); - verify(rangeBackward(bb(6), bb(2)), 6, 4, 2); - } - @Test public void backwardSeekDeprecated() { final ByteBuffer key = bb(6); @@ -102,23 +130,6 @@ public void backwardSeekDeprecated() { } } - @Test - public void backwardStart() { - verify(atLeastBackward(bb(5)), 4, 2); - verify(atLeastBackward(bb(6)), 6, 4, 2); - } - - @Test - public void backwardStop() { - verify(atMostBackward(bb(5)), 8, 6); - verify(atMostBackward(bb(6)), 8, 6); - } - - @Test - public void backwardTest() { - verify(backward(), 8, 6, 4, 2); - } - @Before public void before() throws IOException { final File path = tmp.newFile(); @@ -136,6 +147,18 @@ public void before() throws IOException { } } + @Test + public void closedBackwardTest() { + verify(closedBackward(bb(7), bb(3)), 6, 4); + verify(closedBackward(bb(6), bb(2)), 6, 4, 2); + } + + @Test + public void closedTest() { + verify(closed(bb(3), bb(7)), 4, 6); + verify(closed(bb(2), bb(6)), 2, 4, 6); + } + @Test public void forwardDeprecated() { try (Txn txn = env.txnRead(); @@ -148,12 +171,6 @@ public void forwardDeprecated() { } } - @Test - public void forwardRange() { - verify(range(bb(3), bb(7)), 4, 6); - verify(range(bb(2), bb(6)), 2, 4, 6); - } - @Test public void forwardSeekDeprecated() { final ByteBuffer key = bb(4); @@ -169,23 +186,6 @@ public void forwardSeekDeprecated() { } } - @Test - public void forwardStart() { - verify(atLeast(bb(5)), 6, 8); - verify(atLeast(bb(6)), 6, 8); - } - - @Test - public void forwardStop() { - verify(atMost(bb(5)), 2, 4); - verify(atMost(bb(6)), 2, 4, 6); - } - - @Test - public void forwardTest() { - verify(forward(), 2, 4, 6, 8); - } - @Test public void iterate() { try (Txn txn = env.txnRead(); diff --git a/src/test/java/org/lmdbjava/KeyRangeTest.java b/src/test/java/org/lmdbjava/KeyRangeTest.java index 99a62f14..4310ce3c 100644 --- a/src/test/java/org/lmdbjava/KeyRangeTest.java +++ b/src/test/java/org/lmdbjava/KeyRangeTest.java @@ -31,14 +31,14 @@ import static org.lmdbjava.KeyRange.CursorOp.FIRST; import org.lmdbjava.KeyRange.IteratorOp; import static org.lmdbjava.KeyRange.IteratorOp.TERMINATE; +import static org.lmdbjava.KeyRange.all; +import static org.lmdbjava.KeyRange.allBackward; import static org.lmdbjava.KeyRange.atLeast; import static org.lmdbjava.KeyRange.atLeastBackward; import static org.lmdbjava.KeyRange.atMost; import static org.lmdbjava.KeyRange.atMostBackward; -import static org.lmdbjava.KeyRange.backward; -import static org.lmdbjava.KeyRange.forward; -import static org.lmdbjava.KeyRange.range; -import static org.lmdbjava.KeyRange.rangeBackward; +import static org.lmdbjava.KeyRange.closed; +import static org.lmdbjava.KeyRange.closedBackward; /** * Test {@link KeyRange}. @@ -53,26 +53,37 @@ public final class KeyRangeTest { private final FakeCursor cursor = new FakeCursor(); @Test - public void backwardRange() { - verify(rangeBackward(7, 3), 6, 4); - verify(rangeBackward(6, 2), 6, 4, 2); + public void allBackwardTest() { + verify(allBackward(), 8, 6, 4, 2); } @Test - public void backwardStart() { + public void allTest() { + verify(all(), 2, 4, 6, 8); + } + + @Test + public void atLeastBackwardTest() { verify(atLeastBackward(5), 4, 2); verify(atLeastBackward(6), 6, 4, 2); } @Test - public void backwardStop() { + public void atLeastTest() { + verify(atLeast(5), 6, 8); + verify(atLeast(6), 6, 8); + } + + @Test + public void atMostBackwardTest() { verify(atMostBackward(5), 8, 6); verify(atMostBackward(6), 8, 6); } @Test - public void backwardTest() { - verify(backward(), 8, 6, 4, 2); + public void atMostTest() { + verify(atMost(5), 2, 4); + verify(atMost(6), 2, 4, 6); } @Before @@ -80,6 +91,18 @@ public void before() { cursor.reset(); } + @Test + public void closedBackwardTest() { + verify(closedBackward(7, 3), 6, 4); + verify(closedBackward(6, 2), 6, 4, 2); + } + + @Test + public void closedTest() { + verify(closed(3, 7), 4, 6); + verify(closed(2, 6), 2, 4, 6); + } + @Test public void fakeCursor() { assertThat(cursor.first(), is(2)); @@ -96,29 +119,6 @@ public void fakeCursor() { assertThat(cursor.getWithSetRange(100), nullValue()); } - @Test - public void forwardRange() { - verify(range(3, 7), 4, 6); - verify(range(2, 6), 2, 4, 6); - } - - @Test - public void forwardStart() { - verify(atLeast(5), 6, 8); - verify(atLeast(6), 6, 8); - } - - @Test - public void forwardStop() { - verify(atMost(5), 2, 4); - verify(atMost(6), 2, 4, 6); - } - - @Test - public void forwardTest() { - verify(forward(), 2, 4, 6, 8); - } - private void verify(final KeyRange range, final int... expected) { final List results = new ArrayList<>(); diff --git a/src/test/java/org/lmdbjava/TutorialTest.java b/src/test/java/org/lmdbjava/TutorialTest.java index 8b08914e..4409b6a0 100644 --- a/src/test/java/org/lmdbjava/TutorialTest.java +++ b/src/test/java/org/lmdbjava/TutorialTest.java @@ -321,7 +321,7 @@ public void tutorial4() throws IOException { // Each iterator uses a cursor and must be closed when finished. // Iterate forward in terms of key ordering starting with the first key. - try (CursorIterator it = db.iterate(txn, KeyRange.forward())) { + try (CursorIterator it = db.iterate(txn, KeyRange.all())) { for (final KeyVal kv : it.iterable()) { assertThat(kv.key(), notNullValue()); assertThat(kv.val(), notNullValue()); @@ -329,7 +329,8 @@ public void tutorial4() throws IOException { } // Iterate backward in terms of key ordering starting with the last key. - try (CursorIterator it = db.iterate(txn, KeyRange.backward())) { + try (CursorIterator it = db.iterate(txn, + KeyRange.allBackward())) { for (final KeyVal kv : it.iterable()) { assertThat(kv.key(), notNullValue()); assertThat(kv.val(), notNullValue()); @@ -337,7 +338,8 @@ public void tutorial4() throws IOException { } // There are many ways to control the desired key range via KeyRange, such - // as arbitrary start and stop values, directions etc. + // as arbitrary start and stop values, direction etc. We've adopted Guava's + // terminology for our range classes (see KeyRangeType for further details). key.putInt(1); final KeyRange range = KeyRange.atLeastBackward(key); try (CursorIterator it = db.iterate(txn, range)) {