Skip to content

Commit 43ac84f

Browse files
authored
Merge pull request #255 from LambdAurora/fix/bufferproxy_out_ignored
Fix resulting buffer from BufferProxy's out method being ignored.
2 parents 0b741e8 + 58a489f commit 43ac84f

File tree

4 files changed

+90
-36
lines changed

4 files changed

+90
-36
lines changed

src/main/java/org/lmdbjava/Dbi.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,8 @@ public final class Dbi<T> {
8181
if (nativeCb) {
8282
this.ccb =
8383
(keyA, keyB) -> {
84-
final T compKeyA = proxy.allocate();
85-
final T compKeyB = proxy.allocate();
86-
proxy.out(compKeyA, keyA);
87-
proxy.out(compKeyB, keyB);
84+
final T compKeyA = proxy.out(proxy.allocate(), keyA);
85+
final T compKeyB = proxy.out(proxy.allocate(), keyB);
8886
final int result = this.comparator.compare(compKeyA, compKeyB);
8987
proxy.deallocate(compKeyA);
9088
proxy.deallocate(compKeyB);

src/test/java/org/lmdbjava/ComparatorTest.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,12 @@ public static Object[] data() {
6767
final ComparatorRunner string = new StringRunner();
6868
final ComparatorRunner db = new DirectBufferRunner();
6969
final ComparatorRunner ba = new ByteArrayRunner();
70+
final ComparatorRunner baUnsigned = new UnsignedByteArrayRunner();
7071
final ComparatorRunner bb = new ByteBufferRunner();
7172
final ComparatorRunner netty = new NettyRunner();
7273
final ComparatorRunner gub = new GuavaUnsignedBytes();
7374
final ComparatorRunner gsb = new GuavaSignedBytes();
74-
return new Object[] {string, db, ba, bb, netty, gub, gsb};
75+
return new Object[] {string, db, ba, baUnsigned, bb, netty, gub, gsb};
7576
}
7677

7778
private static byte[] buffer(final int... bytes) {
@@ -140,6 +141,16 @@ public int compare(final byte[] o1, final byte[] o2) {
140141
}
141142
}
142143

144+
/** Tests {@link ByteArrayProxy} (unsigned). */
145+
private static final class UnsignedByteArrayRunner implements ComparatorRunner {
146+
147+
@Override
148+
public int compare(final byte[] o1, final byte[] o2) {
149+
final Comparator<byte[]> c = PROXY_BA.getUnsignedComparator();
150+
return c.compare(o1, o2);
151+
}
152+
}
153+
143154
/** Tests {@link ByteBufferProxy}. */
144155
private static final class ByteBufferRunner implements ComparatorRunner {
145156

src/test/java/org/lmdbjava/DbiTest.java

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@
4646
import static org.lmdbjava.KeyRange.atMost;
4747
import static org.lmdbjava.PutFlags.MDB_NODUPDATA;
4848
import static org.lmdbjava.PutFlags.MDB_NOOVERWRITE;
49-
import static org.lmdbjava.TestUtils.DB_1;
50-
import static org.lmdbjava.TestUtils.ba;
51-
import static org.lmdbjava.TestUtils.bb;
49+
import static org.lmdbjava.TestUtils.*;
5250

5351
import java.io.File;
5452
import java.io.IOException;
@@ -63,8 +61,7 @@
6361
import java.util.concurrent.Future;
6462
import java.util.concurrent.TimeoutException;
6563
import java.util.concurrent.atomic.AtomicBoolean;
66-
import java.util.function.BiConsumer;
67-
import org.agrona.concurrent.UnsafeBuffer;
64+
import java.util.function.*;
6865
import org.hamcrest.Matchers;
6966
import org.junit.After;
7067
import org.junit.Before;
@@ -82,6 +79,7 @@ public final class DbiTest {
8279

8380
@Rule public final TemporaryFolder tmp = new TemporaryFolder();
8481
private Env<ByteBuffer> env;
82+
private Env<byte[]> envBa;
8583

8684
@After
8785
public void after() {
@@ -97,6 +95,13 @@ public void before() throws IOException {
9795
.setMaxReaders(2)
9896
.setMaxDbs(2)
9997
.open(path, MDB_NOSUBDIR);
98+
final File pathBa = tmp.newFile();
99+
envBa =
100+
create(PROXY_BA)
101+
.setMapSize(MEBIBYTES.toBytes(64))
102+
.setMaxReaders(2)
103+
.setMaxDbs(2)
104+
.open(pathBa, MDB_NOSUBDIR);
100105
}
101106

102107
@Test(expected = ConstantDerivedException.class)
@@ -117,20 +122,41 @@ public void customComparator() {
117122
}
118123
return lexical * -1;
119124
};
120-
final Dbi<ByteBuffer> db = env.openDbi(DB_1, reverseOrder, true, MDB_CREATE);
121-
try (Txn<ByteBuffer> txn = env.txnWrite()) {
122-
assertThat(db.put(txn, bb(2), bb(3)), is(true));
123-
assertThat(db.put(txn, bb(4), bb(6)), is(true));
124-
assertThat(db.put(txn, bb(6), bb(7)), is(true));
125-
assertThat(db.put(txn, bb(8), bb(7)), is(true));
125+
doCustomComparator(env, reverseOrder, TestUtils::bb, ByteBuffer::getInt);
126+
}
127+
128+
@Test
129+
public void customComparatorByteArray() {
130+
final Comparator<byte[]> reverseOrder =
131+
(o1, o2) -> {
132+
final int lexical = PROXY_BA.getComparator().compare(o1, o2);
133+
if (lexical == 0) {
134+
return 0;
135+
}
136+
return lexical * -1;
137+
};
138+
doCustomComparator(envBa, reverseOrder, TestUtils::ba, TestUtils::fromBa);
139+
}
140+
141+
private <T> void doCustomComparator(
142+
Env<T> env,
143+
Comparator<T> comparator,
144+
IntFunction<T> serializer,
145+
ToIntFunction<T> deserializer) {
146+
final Dbi<T> db = env.openDbi(DB_1, comparator, true, MDB_CREATE);
147+
try (Txn<T> txn = env.txnWrite()) {
148+
assertThat(db.put(txn, serializer.apply(2), serializer.apply(3)), is(true));
149+
assertThat(db.put(txn, serializer.apply(4), serializer.apply(6)), is(true));
150+
assertThat(db.put(txn, serializer.apply(6), serializer.apply(7)), is(true));
151+
assertThat(db.put(txn, serializer.apply(8), serializer.apply(7)), is(true));
126152
txn.commit();
127153
}
128-
try (Txn<ByteBuffer> txn = env.txnRead();
129-
CursorIterable<ByteBuffer> ci = db.iterate(txn, atMost(bb(4)))) {
130-
final Iterator<KeyVal<ByteBuffer>> iter = ci.iterator();
131-
assertThat(iter.next().key().getInt(), is(8));
132-
assertThat(iter.next().key().getInt(), is(6));
133-
assertThat(iter.next().key().getInt(), is(4));
154+
try (Txn<T> txn = env.txnRead();
155+
CursorIterable<T> ci = db.iterate(txn, atMost(serializer.apply(4)))) {
156+
final Iterator<KeyVal<T>> iter = ci.iterator();
157+
assertThat(deserializer.applyAsInt(iter.next().key()), is(8));
158+
assertThat(deserializer.applyAsInt(iter.next().key()), is(6));
159+
assertThat(deserializer.applyAsInt(iter.next().key()), is(4));
134160
}
135161
}
136162

@@ -143,9 +169,24 @@ public void dbOpenMaxDatabases() {
143169

144170
@Test
145171
public void dbiWithComparatorThreadSafety() {
172+
doDbiWithComparatorThreadSafety(
173+
env, PROXY_OPTIMAL::getComparator, TestUtils::bb, ByteBuffer::getInt);
174+
}
175+
176+
@Test
177+
public void dbiWithComparatorThreadSafetyByteArray() {
178+
doDbiWithComparatorThreadSafety(
179+
envBa, PROXY_BA::getComparator, TestUtils::ba, TestUtils::fromBa);
180+
}
181+
182+
public <T> void doDbiWithComparatorThreadSafety(
183+
Env<T> env,
184+
Function<DbiFlags[], Comparator<T>> comparator,
185+
IntFunction<T> serializer,
186+
ToIntFunction<T> deserializer) {
146187
final DbiFlags[] flags = new DbiFlags[] {MDB_CREATE, MDB_INTEGERKEY};
147-
final Comparator<ByteBuffer> c = PROXY_OPTIMAL.getComparator(flags);
148-
final Dbi<ByteBuffer> db = env.openDbi(DB_1, c, true, flags);
188+
final Comparator<T> c = comparator.apply(flags);
189+
final Dbi<T> db = env.openDbi(DB_1, c, true, flags);
149190

150191
final List<Integer> keys = range(0, 1_000).boxed().collect(toList());
151192

@@ -155,25 +196,25 @@ public void dbiWithComparatorThreadSafety() {
155196
pool.submit(
156197
() -> {
157198
while (proceed.get()) {
158-
try (Txn<ByteBuffer> txn = env.txnRead()) {
159-
db.get(txn, bb(50));
199+
try (Txn<T> txn = env.txnRead()) {
200+
db.get(txn, serializer.apply(50));
160201
}
161202
}
162203
});
163204

164205
for (final Integer key : keys) {
165-
try (Txn<ByteBuffer> txn = env.txnWrite()) {
166-
db.put(txn, bb(key), bb(3));
206+
try (Txn<T> txn = env.txnWrite()) {
207+
db.put(txn, serializer.apply(key), serializer.apply(3));
167208
txn.commit();
168209
}
169210
}
170211

171-
try (Txn<ByteBuffer> txn = env.txnRead();
172-
CursorIterable<ByteBuffer> ci = db.iterate(txn)) {
173-
final Iterator<KeyVal<ByteBuffer>> iter = ci.iterator();
212+
try (Txn<T> txn = env.txnRead();
213+
CursorIterable<T> ci = db.iterate(txn)) {
214+
final Iterator<KeyVal<T>> iter = ci.iterator();
174215
final List<Integer> result = new ArrayList<>();
175216
while (iter.hasNext()) {
176-
result.add(iter.next().key().getInt());
217+
result.add(deserializer.applyAsInt(iter.next().key()));
177218
}
178219

179220
assertThat(result, Matchers.contains(keys.toArray(new Integer[0])));
@@ -339,7 +380,7 @@ public void putCommitGetByteArray() throws IOException {
339380
try (Txn<byte[]> txn = envBa.txnWrite()) {
340381
final byte[] found = db.get(txn, ba(5));
341382
assertNotNull(found);
342-
assertThat(new UnsafeBuffer(txn.val()).getInt(0), is(5));
383+
assertThat(fromBa(txn.val()), is(5));
343384
}
344385
}
345386
}

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,13 @@ final class TestUtils {
3636
private TestUtils() {}
3737

3838
static byte[] ba(final int value) {
39-
final MutableDirectBuffer b = new UnsafeBuffer(new byte[4]);
40-
b.putInt(0, value);
41-
return b.byteArray();
39+
byte[] bytes = new byte[4];
40+
ByteBuffer.wrap(bytes).putInt(value);
41+
return bytes;
42+
}
43+
44+
static int fromBa(final byte[] ba) {
45+
return ByteBuffer.wrap(ba).getInt();
4246
}
4347

4448
static ByteBuffer bb(final int value) {

0 commit comments

Comments
 (0)