-
Notifications
You must be signed in to change notification settings - Fork 123
Closed
Description
There seems to be a problem with the byte buffer comparator that occurs when the buffers are larger than the value they hold and it is comparing values of different lengths. The test below illustrates the problem. When comparing key301
to key30
it is getting the wrong result so is incorrectly carrying on past it. When run it finds 6 entries not 3.
I will raise a PR in a minute with the fix to the comparator.
package org.lmdbjava;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class ClosedOpenTest {
@Rule
public final TemporaryFolder tmp = new TemporaryFolder();
@Test
public void testClosedOpen() throws IOException {
final File path = tmp.newFile();
final Env<ByteBuffer> env = Env.create()
.setMapSize(1024 * 100)
.setMaxReaders(1)
.setMaxDbs(1)
.open(path, TestUtils.POSIX_MODE, EnvFlags.MDB_NOSUBDIR);
final Dbi<ByteBuffer> db = env.openDbi(TestUtils.DB_1, DbiFlags.MDB_CREATE);
try (Txn<ByteBuffer> txn = env.txnWrite()) {
final Cursor<ByteBuffer> c = db.openCursor(txn);
c.put(bb("key101"), bb("val101"));
c.put(bb("key102"), bb("val102"));
c.put(bb("key103"), bb("val103"));
c.put(bb("key201"), bb("val201"));
c.put(bb("key202"), bb("val202"));
c.put(bb("key203"), bb("val203"));
c.put(bb("key301"), bb("val301"));
c.put(bb("key302"), bb("val302"));
c.put(bb("key303"), bb("val303"));
txn.commit();
}
// Should find keys 201, 202 and 203 only
final KeyRange<ByteBuffer> range = KeyRange.closedOpen(
bb("key20"),
bb("key30"));
final List<String> keysFound = new ArrayList<>();
try (final Txn<ByteBuffer> txn = env.txnRead();
final CursorIterable<ByteBuffer> c = db.iterate(txn, range)) {
for (final CursorIterable.KeyVal<ByteBuffer> kv : c) {
final String key = StandardCharsets.UTF_8.decode(kv.key()).toString();
System.out.println(key);
keysFound.add(key);
}
}
Assert.assertEquals(3, keysFound.size());
env.close();
}
private static ByteBuffer bb(final String value) {
// Buffer larger than the value
final ByteBuffer bb = ByteBuffer.allocateDirect(10);
bb.put(value.getBytes(StandardCharsets.UTF_8));
bb.flip();
return bb;
}
}
Metadata
Metadata
Assignees
Labels
No labels