use of com.apple.foundationdb.tuple.ByteArrayUtil.compareUnsigned in project fdb-record-layer by FoundationDB.
the class RangeSetTest method concurrentWithInsert.
// Test out a few of the wild and wacky things that can happen when there are insertions going concurrently.
@Test
@Tag(Tags.Slow)
public void concurrentWithInsert() {
final List<byte[]> keys = createKeys();
final List<Range> ranges = new ArrayList<>();
// Two disjoint ranges -- both should succeed.
Transaction tr1 = db.createTransaction();
Transaction tr2 = db.createTransaction();
Range r1 = new Range(new byte[] { 0x01 }, new byte[] { 0x02 });
Range r2 = new Range(new byte[] { 0x02 }, new byte[] { 0x03 });
CompletableFuture<Boolean> future1 = rs.insertRange(tr1, r1);
CompletableFuture<Boolean> future2 = rs.insertRange(tr2, r2);
assertTrue(future1.join(), "Range 1 did not do insertion.");
assertTrue(future2.join(), "Range 2 did not do insertion.");
tr1.commit().join();
tr2.commit().join();
ranges.add(r1);
ranges.add(r2);
checkConsistent(ranges, keys);
checkIncreasing();
// Two non-disjoint ranges. The second should fail.
tr1 = db.createTransaction();
tr2 = db.createTransaction();
r1 = new Range(new byte[] { 0x03 }, new byte[] { 0x05 });
r2 = new Range(new byte[] { 0x04 }, new byte[] { 0x06 });
future1 = rs.insertRange(tr1, r1);
future2 = rs.insertRange(tr2, r2);
assertTrue(future1.join(), "Range 1 did not do insertion");
assertTrue(future2.join(), "Range 2 did not do insertion");
tr1.commit().join();
tr2.commit().handle((vignore, e) -> {
assertNotNull(e, "No error thrown from commit");
assertTrue(e instanceof FDBException, "Non-FDBException " + e.toString());
FDBException fdbe = (FDBException) e;
assertEquals(FDBError.NOT_COMMITTED.code(), fdbe.getCode(), "Did not get not-committed error.");
return vignore;
}).join();
ranges.add(r1);
checkConsistent(ranges, keys);
checkIncreasing();
// Read during write - the reads in the range should fail.
r1 = new Range(new byte[] { 0x07 }, new byte[] { 0x08 });
List<byte[]> specificKeys = Arrays.asList(new byte[] { 0x06, (byte) 0xff }, new byte[] { 0x07 }, new byte[] { 0x07, 0x00 }, new byte[] { 0x07, 0x10 }, new byte[] { 0x08 }, new byte[] { 0x08, 0x00 }, new byte[] { 0x08, 0x10 }, new byte[] { 0x09 });
tr1 = db.createTransaction();
List<Transaction> transactions = specificKeys.stream().map(ignore -> db.createTransaction()).collect(Collectors.toList());
// Add write conflict ranges to each key so that they are not read only.
transactions.forEach(tr -> tr.addWriteConflictKey(DEADC0DE));
future1 = rs.insertRange(tr1, r1);
List<CompletableFuture<Boolean>> futures = new ArrayList<>();
for (int i = 0; i < specificKeys.size(); i++) {
futures.add(rs.contains(transactions.get(i), specificKeys.get(i)));
}
assertTrue(future1.join(), "Range 1 did not do insertion");
futures.forEach(future -> assertFalse(future.join(), "Key should not be present"));
tr1.commit().join();
Range range = r1;
for (int i = 0; i < transactions.size(); i++) {
final int index = i;
transactions.get(i).commit().handle((vignore, e) -> {
byte[] key = specificKeys.get(index);
String repr = ByteArrayUtil.printable(key);
if (ByteArrayUtil.compareUnsigned(range.begin, key) <= 0 && ByteArrayUtil.compareUnsigned(key, range.end) < 0) {
assertNotNull(e, "No error from commit when key is " + repr);
assertTrue(e instanceof FDBException, "Non-FDBException " + e.toString() + " with key " + repr);
FDBException fdbe = (FDBException) e;
assertEquals(FDBError.NOT_COMMITTED.code(), fdbe.getCode(), "Did not get non-committed error when key is " + repr);
} else {
assertNull(e, "Error when key is " + repr);
}
return vignore;
}).join();
}
ranges.add(r1);
checkConsistent(ranges, keys);
checkIncreasing();
}
Aggregations