Skip to content

Commit

Permalink
Add range support for bidirectional greaterThan (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
benalexau committed Jul 15, 2017
1 parent 68f1310 commit 8b1e5fa
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 2 deletions.
22 changes: 22 additions & 0 deletions src/main/java/org/lmdbjava/KeyRange.java
Expand Up @@ -154,6 +154,28 @@ public static <T> KeyRange<T> closedBackward(final T start, final T stop) {
return new KeyRange<>(KeyRangeType.BACKWARD_CLOSED, start, stop);
}

/**
* Create a {@link KeyRangeType#FORWARD_GREATER_THAN} range.
*
* @param <T> buffer type
* @param start start key (required)
* @return a key range (never null)
*/
public static <T> KeyRange<T> greaterThan(final T start) {
return new KeyRange<>(KeyRangeType.FORWARD_GREATER_THAN, start, null);
}

/**
* Create a {@link KeyRangeType#BACKWARD_GREATER_THAN} range.
*
* @param <T> buffer type
* @param start start key (required)
* @return a key range (never null)
*/
public static <T> KeyRange<T> greaterThanBackward(final T start) {
return new KeyRange<>(KeyRangeType.BACKWARD_GREATER_THAN, start, null);
}

/**
* Start key.
*
Expand Down
37 changes: 35 additions & 2 deletions src/main/java/org/lmdbjava/KeyRangeType.java
Expand Up @@ -45,7 +45,8 @@
* <p>
* In the examples below, it is assumed the table has keys 2, 4, 6 and 8.
*/
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.StdCyclomaticComplexity"})
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.StdCyclomaticComplexity",
"PMD.ModifiedCyclomaticComplexity"})
public enum KeyRangeType {

/**
Expand Down Expand Up @@ -96,6 +97,18 @@ public enum KeyRangeType {
* would be 4 and 6. With a range of 2 - 6, the keys would be 2, 4 and 6.
*/
FORWARD_CLOSED(true, true, true),
/**
* Start after the passed key (but not equal to it) and iterate forward until
* no keys remain.
*
* <p>
* The "start" value is required. The "stop" value is ignored.
*
* <p>
* In our example and with a passed search key of 4, the returned keys would
* be 6 and 8. With a passed key of 3, the returned keys would be 4, 6 and 8.
*/
FORWARD_GREATER_THAN(true, true, false),
/**
* Start on the last key and iterate backward until no keys remain.
*
Expand Down Expand Up @@ -143,7 +156,19 @@ 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_CLOSED(false, true, true);
BACKWARD_CLOSED(false, true, true),
/**
* Start immediate prior to the passed key (but not equal to it) and iterate
* backward until no keys remain.
*
* <p>
* The "start" value is required. The "stop" value is ignored.
*
* <p>
* In our example and with a passed search key of 6, the returned keys would
* be 4 and 2. With a passed key of 7, the returned keys would be 6, 4 and 2.
*/
BACKWARD_GREATER_THAN(false, true, false);

private final boolean directionForward;
private final boolean startKeyRequired;
Expand Down Expand Up @@ -203,6 +228,8 @@ CursorOp initialOp() {
return FIRST;
case FORWARD_CLOSED:
return GET_START_KEY;
case FORWARD_GREATER_THAN:
return GET_START_KEY;
case BACKWARD_ALL:
return LAST;
case BACKWARD_AT_LEAST:
Expand All @@ -211,6 +238,8 @@ CursorOp initialOp() {
return LAST;
case BACKWARD_CLOSED:
return GET_START_KEY;
case BACKWARD_GREATER_THAN:
return GET_START_KEY;
default:
throw new IllegalStateException("Invalid type");
}
Expand Down Expand Up @@ -243,6 +272,8 @@ <T, C extends Comparator<T>> IteratorOp iteratorOp(final T start, final T stop,
return c.compare(buffer, stop) > 0 ? TERMINATE : RELEASE;
case FORWARD_CLOSED:
return c.compare(buffer, stop) > 0 ? TERMINATE : RELEASE;
case FORWARD_GREATER_THAN:
return c.compare(buffer, start) == 0 ? CALL_NEXT_OP : RELEASE;
case BACKWARD_ALL:
return RELEASE;
case BACKWARD_AT_LEAST:
Expand All @@ -254,6 +285,8 @@ <T, C extends Comparator<T>> IteratorOp iteratorOp(final T start, final T stop,
return CALL_NEXT_OP; // rewind
}
return c.compare(buffer, stop) >= 0 ? RELEASE : TERMINATE;
case BACKWARD_GREATER_THAN:
return c.compare(buffer, start) >= 0 ? CALL_NEXT_OP : RELEASE;
default:
throw new IllegalStateException("Invalid type");
}
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/org/lmdbjava/CursorIteratorTest.java
Expand Up @@ -50,6 +50,8 @@
import static org.lmdbjava.KeyRange.atMostBackward;
import static org.lmdbjava.KeyRange.closed;
import static org.lmdbjava.KeyRange.closedBackward;
import static org.lmdbjava.KeyRange.greaterThan;
import static org.lmdbjava.KeyRange.greaterThanBackward;
import static org.lmdbjava.PutFlags.MDB_NOOVERWRITE;
import static org.lmdbjava.TestUtils.DB_1;
import static org.lmdbjava.TestUtils.bb;
Expand Down Expand Up @@ -186,6 +188,18 @@ public void forwardSeekDeprecated() {
}
}

@Test
public void greaterThanBackwardTest() {
verify(greaterThanBackward(bb(6)), 4, 2);
verify(greaterThanBackward(bb(7)), 6, 4, 2);
}

@Test
public void greaterThanTest() {
verify(greaterThan(bb(4)), 6, 8);
verify(greaterThan(bb(3)), 4, 6, 8);
}

@Test
public void iterate() {
try (Txn<ByteBuffer> txn = env.txnRead();
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/org/lmdbjava/KeyRangeTest.java
Expand Up @@ -35,6 +35,8 @@
import static org.lmdbjava.KeyRange.atMostBackward;
import static org.lmdbjava.KeyRange.closed;
import static org.lmdbjava.KeyRange.closedBackward;
import static org.lmdbjava.KeyRange.greaterThan;
import static org.lmdbjava.KeyRange.greaterThanBackward;
import org.lmdbjava.KeyRangeType.CursorOp;
import static org.lmdbjava.KeyRangeType.CursorOp.FIRST;
import org.lmdbjava.KeyRangeType.IteratorOp;
Expand Down Expand Up @@ -119,6 +121,18 @@ public void fakeCursor() {
assertThat(cursor.getWithSetRange(100), nullValue());
}

@Test
public void greaterThanBackwardTest() {
verify(greaterThanBackward(6), 4, 2);
verify(greaterThanBackward(7), 6, 4, 2);
}

@Test
public void greaterThanTest() {
verify(greaterThan(4), 6, 8);
verify(greaterThan(3), 4, 6, 8);
}

private void verify(final KeyRange<Integer> range, final int... expected) {
final List<Integer> results = new ArrayList<>();

Expand Down

0 comments on commit 8b1e5fa

Please sign in to comment.