Skip to content

Commit a84ceaa

Browse files
committed
Change CursorIterableRangeTest to do default+native modes
1 parent 2bfe07c commit a84ceaa

File tree

4 files changed

+203
-44
lines changed

4 files changed

+203
-44
lines changed

src/main/java/org/lmdbjava/Key.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
import jnr.ffi.provider.MemoryManager;
2424

2525
/**
26-
* Represents off-heap memory holding a key only.
27-
* Equivalent to {@link KeyVal} without the val part.
26+
* Represents off-heap memory holding a key only. Equivalent to {@link KeyVal} without the val part.
2827
*
2928
* @param <T> buffer type
3029
*/

src/test/java/org/lmdbjava/CursorIterableRangeTest.java

Lines changed: 81 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,8 @@
1818

1919
import static java.nio.ByteBuffer.allocateDirect;
2020
import static org.assertj.core.api.Assertions.assertThat;
21-
import static org.lmdbjava.DbiFlags.MDB_CREATE;
22-
import static org.lmdbjava.DbiFlags.MDB_DUPSORT;
23-
import static org.lmdbjava.DbiFlags.MDB_INTEGERKEY;
2421
import static org.lmdbjava.Env.create;
25-
import static org.lmdbjava.EnvFlags.MDB_NOSUBDIR;
2622
import static org.lmdbjava.TestUtils.DB_1;
27-
import static org.lmdbjava.TestUtils.POSIX_MODE;
2823
import static org.lmdbjava.TestUtils.bb;
2924

3025
import java.io.File;
@@ -41,14 +36,19 @@
4136
import java.util.function.Function;
4237
import org.junit.jupiter.params.ParameterizedTest;
4338
import org.junit.jupiter.params.provider.CsvFileSource;
44-
import org.lmdbjava.ByteBufferProxy.AbstractByteBufferProxy;
4539
import org.lmdbjava.CursorIterable.KeyVal;
4640

4741
/** Test {@link CursorIterable}. */
4842
public final class CursorIterableRangeTest {
4943

50-
private static final DbiFlagSet CREATE_AND_DUPSORT = DbiFlagSet.of(MDB_CREATE, MDB_DUPSORT);
51-
private static final DbiFlagSet CREATE_AND_INTEGERKEY = DbiFlagSet.of(MDB_CREATE, MDB_INTEGERKEY);
44+
private static final DbiFlagSet FLAGSET_DUPSORT =
45+
DbiFlagSet.of(DbiFlags.MDB_CREATE, DbiFlags.MDB_DUPSORT);
46+
private static final DbiFlagSet FLAGSET_REVERSEKEY =
47+
DbiFlagSet.of(DbiFlags.MDB_CREATE, DbiFlags.MDB_REVERSEKEY);
48+
private static final DbiFlagSet FLAGSET_INTEGERKEY =
49+
DbiFlagSet.of(DbiFlags.MDB_CREATE, DbiFlags.MDB_INTEGERKEY);
50+
private static final DbiFlagSet FLAGSET_REVERSE_INTEGERKEY =
51+
DbiFlagSet.of(DbiFlags.MDB_CREATE, DbiFlags.MDB_INTEGERKEY, DbiFlags.MDB_REVERSEKEY);
5252

5353
@ParameterizedTest(name = "{index} => {0}: ({1}, {2})")
5454
@CsvFileSource(resources = "/CursorIterableRangeTest/testSignedComparator.csv")
@@ -57,7 +57,7 @@ void testSignedComparator(
5757
testCSV(
5858
builder -> builder.withCallbackComparator(ignored -> ByteBuffer::compareTo),
5959
createBasicDBPopulator(),
60-
MDB_CREATE,
60+
DbiFlags.MDB_CREATE,
6161
keyType,
6262
startKey,
6363
stopKey,
@@ -68,16 +68,21 @@ void testSignedComparator(
6868
@CsvFileSource(resources = "/CursorIterableRangeTest/testUnsignedComparator.csv")
6969
void testUnsignedComparator(
7070
final String keyType, final String startKey, final String stopKey, final String expectedKV) {
71-
testCSV(
72-
builder ->
73-
builder.withIteratorComparator(
74-
ignored -> AbstractByteBufferProxy::compareLexicographically),
75-
createBasicDBPopulator(),
76-
MDB_CREATE,
77-
keyType,
78-
startKey,
79-
stopKey,
80-
expectedKV);
71+
testCSV(createBasicDBPopulator(), DbiFlags.MDB_CREATE, keyType, startKey, stopKey, expectedKV);
72+
}
73+
74+
@ParameterizedTest(name = "{index} => {0}: ({1}, {2})")
75+
@CsvFileSource(resources = "/CursorIterableRangeTest/testUnsignedComparator.csv")
76+
void testUnsignedComparator_Iterator(
77+
final String keyType, final String startKey, final String stopKey, final String expectedKV) {
78+
testCSV(createBasicDBPopulator(), DbiFlags.MDB_CREATE, keyType, startKey, stopKey, expectedKV);
79+
}
80+
81+
@ParameterizedTest(name = "{index} => {0}: ({1}, {2})")
82+
@CsvFileSource(resources = "/CursorIterableRangeTest/testUnsignedComparator.csv")
83+
void testUnsignedComparator_Callback(
84+
final String keyType, final String startKey, final String stopKey, final String expectedKV) {
85+
testCSV(createBasicDBPopulator(), DbiFlags.MDB_CREATE, keyType, startKey, stopKey, expectedKV);
8186
}
8287

8388
@ParameterizedTest(name = "{index} => {0}: ({1}, {2})")
@@ -87,7 +92,7 @@ void testSignedComparatorDupsort(
8792
testCSV(
8893
builder -> builder.withCallbackComparator(ignored -> ByteBuffer::compareTo),
8994
createMultiDBPopulator(2),
90-
CREATE_AND_DUPSORT,
95+
FLAGSET_DUPSORT,
9196
keyType,
9297
startKey,
9398
stopKey,
@@ -98,28 +103,16 @@ void testSignedComparatorDupsort(
98103
@CsvFileSource(resources = "/CursorIterableRangeTest/testUnsignedComparatorDupsort.csv")
99104
void testUnsignedComparatorDupsort(
100105
final String keyType, final String startKey, final String stopKey, final String expectedKV) {
101-
testCSV(
102-
builder ->
103-
builder.withIteratorComparator(
104-
ignored -> AbstractByteBufferProxy::compareLexicographically),
105-
createMultiDBPopulator(2),
106-
CREATE_AND_DUPSORT,
107-
keyType,
108-
startKey,
109-
stopKey,
110-
expectedKV);
106+
testCSV(createMultiDBPopulator(2), FLAGSET_DUPSORT, keyType, startKey, stopKey, expectedKV);
111107
}
112108

113109
@ParameterizedTest(name = "{index} => {0}: ({1}, {2})")
114110
@CsvFileSource(resources = "/CursorIterableRangeTest/testIntegerKey.csv")
115111
void testIntegerKey(
116112
final String keyType, final String startKey, final String stopKey, final String expectedKV) {
117113
testCSV(
118-
builder ->
119-
builder.withIteratorComparator(
120-
ignored -> AbstractByteBufferProxy::compareAsIntegerKeys),
121114
createIntegerDBPopulator(),
122-
DbiFlagSet.of(MDB_CREATE, MDB_INTEGERKEY),
115+
FLAGSET_INTEGERKEY,
123116
keyType,
124117
startKey,
125118
stopKey,
@@ -133,11 +126,8 @@ void testIntegerKey(
133126
void testLongKey(
134127
final String keyType, final String startKey, final String stopKey, final String expectedKV) {
135128
testCSV(
136-
builder ->
137-
builder.withIteratorComparator(
138-
ignored -> AbstractByteBufferProxy::compareAsIntegerKeys),
139129
createLongDBPopulator(),
140-
CREATE_AND_INTEGERKEY,
130+
FLAGSET_INTEGERKEY,
141131
keyType,
142132
startKey,
143133
stopKey,
@@ -166,6 +156,58 @@ private void testCSV(
166156
ByteOrder.BIG_ENDIAN);
167157
}
168158

159+
private void testCSV(
160+
final BiConsumer<Env<ByteBuffer>, Dbi<ByteBuffer>> dbPopulator,
161+
final DbiFlagSet dbiFlags,
162+
final String keyType,
163+
final String startKey,
164+
final String stopKey,
165+
final String expectedKV) {
166+
testCSV(
167+
dbPopulator,
168+
dbiFlags,
169+
keyType,
170+
startKey,
171+
stopKey,
172+
expectedKV,
173+
Integer.BYTES,
174+
ByteOrder.BIG_ENDIAN);
175+
}
176+
177+
private void testCSV(
178+
final BiConsumer<Env<ByteBuffer>, Dbi<ByteBuffer>> dbPopulator,
179+
final DbiFlagSet dbiFlags,
180+
final String keyType,
181+
final String startKey,
182+
final String stopKey,
183+
final String expectedKV,
184+
final int keyLen,
185+
final ByteOrder byteOrder) {
186+
// First test with our default iterator comparator
187+
testCSV(
188+
DbiBuilder.Stage2::withDefaultComparator,
189+
dbPopulator,
190+
dbiFlags,
191+
keyType,
192+
startKey,
193+
stopKey,
194+
expectedKV,
195+
keyLen,
196+
byteOrder);
197+
198+
// Now test with mdp_cmp doing all comparisons, should be the same
199+
testCSV(
200+
DbiBuilder.Stage2::withNativeComparator,
201+
dbPopulator,
202+
dbiFlags,
203+
keyType,
204+
startKey,
205+
stopKey,
206+
expectedKV,
207+
keyLen,
208+
byteOrder);
209+
}
210+
169211
private void testCSV(
170212
final Function<DbiBuilder.Stage2<ByteBuffer>, DbiBuilder.Stage3<ByteBuffer>> comparatorFunc,
171213
final BiConsumer<Env<ByteBuffer>, Dbi<ByteBuffer>> dbPopulator,
@@ -183,8 +225,7 @@ private void testCSV(
183225
.setMapSize(256, ByteUnit.KIBIBYTES)
184226
.setMaxReaders(1)
185227
.setMaxDbs(1)
186-
.setFilePermissions(POSIX_MODE)
187-
.setEnvFlags(MDB_NOSUBDIR)
228+
.setEnvFlags(EnvFlags.MDB_NOSUBDIR)
188229
.open(file)) {
189230

190231
final DbiBuilder.Stage2<ByteBuffer> builderStage2 = env.createDbi().setDbName(DB_1);

src/test/java/org/lmdbjava/TestUtils.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ final class TestUtils {
3838
public static final String DB_3 = "test-db-3";
3939
public static final String DB_4 = "test-db-2";
4040

41-
public static final int POSIX_MODE = 0664;
42-
4341
private TestUtils() {}
4442

4543
static byte[] ba(final int value) {

src/test/java/org/lmdbjava/TutorialTest.java

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,19 @@
2222
import static org.lmdbjava.ByteBufferProxy.PROXY_OPTIMAL;
2323
import static org.lmdbjava.DbiFlags.MDB_CREATE;
2424
import static org.lmdbjava.DbiFlags.MDB_DUPSORT;
25+
import static org.lmdbjava.DbiFlags.MDB_INTEGERKEY;
26+
import static org.lmdbjava.DbiFlags.MDB_REVERSEKEY;
2527
import static org.lmdbjava.DirectBufferProxy.PROXY_DB;
2628
import static org.lmdbjava.GetOp.MDB_SET;
2729
import static org.lmdbjava.SeekOp.MDB_FIRST;
2830
import static org.lmdbjava.SeekOp.MDB_LAST;
2931
import static org.lmdbjava.SeekOp.MDB_PREV;
3032

3133
import java.nio.ByteBuffer;
34+
import java.nio.ByteOrder;
3235
import java.nio.file.Path;
36+
import java.util.ArrayList;
37+
import java.util.List;
3338
import java.util.concurrent.ExecutorService;
3439
import java.util.concurrent.Executors;
3540
import org.agrona.DirectBuffer;
@@ -470,6 +475,122 @@ void tutorial7() {
470475
env.close();
471476
}
472477

478+
/**
479+
* In this tutorial we'll look at using keys that are longs. The same approach applies would apply
480+
* to int keys.
481+
*/
482+
@Test
483+
void tutorial8() {
484+
final Path dir = tempDir.createTempDir();
485+
final Env<ByteBuffer> env = createSimpleEnv(dir);
486+
487+
// This time we're going to tell the Dbi that all the keys are integers.
488+
// MDB_INTEGERKEY applies to both int and long keys.
489+
// LMDB can make optimisations for better performance.
490+
final Dbi<ByteBuffer> db = env.openDbi(DB_NAME, DbiFlagSet.of(MDB_CREATE, MDB_INTEGERKEY));
491+
492+
// MDB_INTEGERKEY requires that the keys are written/read in native order
493+
final ByteBuffer key = ByteBuffer.allocateDirect(Long.BYTES).order(ByteOrder.nativeOrder());
494+
final ByteBuffer val = ByteBuffer.allocateDirect(100);
495+
496+
try (Txn<ByteBuffer> txn = env.txnWrite()) {
497+
498+
// Store one key, but many values, and in non-natural order.
499+
key.putLong(42L).flip();
500+
val.put("val-42".getBytes(UTF_8)).flip();
501+
db.put(txn, key, val);
502+
503+
key.clear();
504+
val.clear();
505+
key.putLong(1L).flip();
506+
val.put("val-1".getBytes(UTF_8)).flip();
507+
db.put(txn, key, val);
508+
509+
key.clear();
510+
val.clear();
511+
key.putLong(Long.MAX_VALUE).flip();
512+
val.put(("val-" + Long.MAX_VALUE).getBytes(UTF_8)).flip();
513+
db.put(txn, key, val);
514+
515+
key.clear();
516+
val.clear();
517+
key.putLong(1_000L).flip();
518+
val.put("val-1".getBytes(UTF_8)).flip();
519+
db.put(txn, key, val);
520+
521+
// Get all the keys
522+
final List<Long> keys = new ArrayList<>();
523+
try (CursorIterable<ByteBuffer> ci = db.iterate(txn, KeyRange.all())) {
524+
for (final KeyVal<ByteBuffer> kv : ci) {
525+
assertThat(kv.key()).isNotNull();
526+
assertThat(kv.val()).isNotNull();
527+
keys.add(kv.key().order(ByteOrder.nativeOrder()).getLong());
528+
}
529+
}
530+
531+
assertThat(keys).containsExactly(1L, 42L, 1_000L, Long.MAX_VALUE);
532+
533+
txn.commit();
534+
}
535+
env.close();
536+
}
537+
538+
/** In this tutorial we'll look storing the data in reverse order */
539+
@Test
540+
void tutorial9() {
541+
final Path dir = tempDir.createTempDir();
542+
final Env<ByteBuffer> env = createSimpleEnv(dir);
543+
544+
final Dbi<ByteBuffer> db = env.openDbi(DB_NAME, DbiFlagSet.of(MDB_CREATE, MDB_REVERSEKEY));
545+
546+
final ByteBuffer key = ByteBuffer.allocateDirect(100);
547+
final ByteBuffer val = ByteBuffer.allocateDirect(100);
548+
549+
try (Txn<ByteBuffer> txn = env.txnWrite()) {
550+
551+
// Store one key, but many values, and in non-natural order.
552+
key.put("tac".getBytes(UTF_8)).flip();
553+
val.put("CAT".getBytes(UTF_8)).flip();
554+
db.put(txn, key, val);
555+
556+
key.clear();
557+
val.clear();
558+
key.put("god".getBytes(UTF_8)).flip();
559+
val.put("DOG".getBytes(UTF_8)).flip();
560+
db.put(txn, key, val);
561+
562+
key.clear();
563+
val.clear();
564+
key.put("esroh".getBytes(UTF_8)).flip();
565+
val.put("HORSE".getBytes(UTF_8)).flip();
566+
db.put(txn, key, val);
567+
568+
key.clear();
569+
val.clear();
570+
key.put("tnahpele".getBytes(UTF_8)).flip();
571+
val.put("ELEPHANT".getBytes(UTF_8)).flip();
572+
db.put(txn, key, val);
573+
574+
// Get all the keys
575+
final List<String> keys = new ArrayList<>();
576+
final List<String> values = new ArrayList<>();
577+
try (CursorIterable<ByteBuffer> ci = db.iterate(txn, KeyRange.all())) {
578+
for (final KeyVal<ByteBuffer> kv : ci) {
579+
assertThat(kv.key()).isNotNull();
580+
assertThat(kv.val()).isNotNull();
581+
keys.add(UTF_8.decode(kv.key()).toString());
582+
values.add(UTF_8.decode(kv.val()).toString());
583+
}
584+
}
585+
586+
assertThat(keys).containsExactly("tac", "god", "tnahpele", "esroh");
587+
assertThat(values).containsExactly("CAT", "DOG", "ELEPHANT", "HORSE");
588+
589+
txn.commit();
590+
}
591+
env.close();
592+
}
593+
473594
// You've finished! There are lots of other neat things we could show you (eg
474595
// how to speed up inserts by appending them in key order, using integer
475596
// or reverse ordered keys, using Env.DISABLE_CHECKS_PROP etc), but you now

0 commit comments

Comments
 (0)