use of com.apple.foundationdb.Range in project fdb-record-layer by FoundationDB.
the class TupleRangeTest method toRange.
@Test
public void toRange() {
final Tuple a = Tuple.from("a");
final Tuple b = Tuple.from("b");
List<Pair<TupleRange, Range>> testCases = Arrays.asList(Pair.of(TupleRange.allOf(null), new Range(new byte[0], new byte[] { (byte) 0xff })), Pair.of(TupleRange.allOf(PREFIX_TUPLE), Range.startsWith(PREFIX_BYTES)), Pair.of(new TupleRange(a, b, EndpointType.RANGE_INCLUSIVE, EndpointType.RANGE_EXCLUSIVE), new Range(a.pack(), b.pack())), Pair.of(new TupleRange(a, b, EndpointType.RANGE_INCLUSIVE, EndpointType.RANGE_INCLUSIVE), new Range(a.pack(), ByteArrayUtil.strinc(b.pack()))), Pair.of(new TupleRange(a, b, EndpointType.RANGE_EXCLUSIVE, EndpointType.RANGE_EXCLUSIVE), new Range(ByteArrayUtil.strinc(a.pack()), b.pack())), Pair.of(new TupleRange(a, b, EndpointType.RANGE_EXCLUSIVE, EndpointType.RANGE_INCLUSIVE), new Range(ByteArrayUtil.strinc(a.pack()), ByteArrayUtil.strinc(b.pack()))), Pair.of(new TupleRange(null, b, EndpointType.TREE_START, EndpointType.RANGE_EXCLUSIVE), new Range(new byte[0], b.pack())), Pair.of(new TupleRange(a, null, EndpointType.RANGE_INCLUSIVE, EndpointType.TREE_END), new Range(a.pack(), new byte[] { (byte) 0xff })), Pair.of(new TupleRange(a, b, EndpointType.CONTINUATION, EndpointType.RANGE_EXCLUSIVE), new Range(ByteArrayUtil.join(a.pack(), new byte[] { 0x00 }), b.pack())), Pair.of(new TupleRange(a, b, EndpointType.RANGE_INCLUSIVE, EndpointType.CONTINUATION), new Range(a.pack(), b.pack())), Pair.of(TupleRange.prefixedBy("a"), new Range(new byte[] { 0x02, (byte) 'a' }, new byte[] { 0x02, (byte) 'b' })), Pair.of(new TupleRange(Tuple.from("apple"), a, EndpointType.CONTINUATION, EndpointType.PREFIX_STRING), new Range(ByteArrayUtil.join(Tuple.from("apple").pack(), new byte[] { 0x00 }), new byte[] { 0x02, (byte) 'b' })), Pair.of(new TupleRange(a, Tuple.from("apple"), EndpointType.PREFIX_STRING, EndpointType.CONTINUATION), new Range(new byte[] { 0x02, (byte) 'a' }, Tuple.from("apple").pack())));
testCases.forEach(pair -> {
assertEquals(pair.getRight(), pair.getLeft().toRange());
TupleRange expectedRange = pair.getLeft().prepend(PREFIX_TUPLE);
assertEquals(expectedRange.toRange(), pair.getLeft().toRange(PREFIX_SUBSPACE));
});
}
use of com.apple.foundationdb.Range in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreTest method testOverlappingPrimaryKey.
@Test
public void testOverlappingPrimaryKey() {
try (FDBRecordContext context = openContext()) {
RecordMetaDataBuilder builder = RecordMetaData.newBuilder().setRecords(TestRecordsWithHeaderProto.getDescriptor());
builder.getRecordType("MyRecord").setPrimaryKey(field("header").nest(concatenateFields("path", "rec_no")));
builder.addIndex("MyRecord", "MyRecord$path_str", concat(field("header").nest("path"), field("str_value")));
RecordMetaData metaData = builder.getRecordMetaData();
createOrOpenRecordStore(context, metaData);
TestRecordsWithHeaderProto.MyRecord.Builder recBuilder = TestRecordsWithHeaderProto.MyRecord.newBuilder();
TestRecordsWithHeaderProto.HeaderRecord.Builder headerBuilder = recBuilder.getHeaderBuilder();
headerBuilder.setPath("aaa");
headerBuilder.setRecNo(1);
recBuilder.setStrValue("hello");
recordStore.saveRecord(recBuilder.build());
headerBuilder.setPath("aaa");
headerBuilder.setRecNo(2);
recBuilder.setStrValue("goodbye");
recordStore.saveRecord(recBuilder.build());
headerBuilder.setPath("zzz");
headerBuilder.setRecNo(3);
recBuilder.setStrValue("end");
recordStore.saveRecord(recBuilder.build());
List<List<Object>> rows = new ArrayList<>();
Index index = metaData.getIndex("MyRecord$path_str");
ScanComparisons comparisons = ScanComparisons.from(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, "aaa"));
TupleRange range = comparisons.toTupleRange();
try (RecordCursor<IndexEntry> cursor = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN)) {
cursor.forEach(row -> rows.add(row.getKey().getItems())).join();
}
assertEquals(Arrays.asList(Arrays.asList("aaa", "goodbye", 2L), Arrays.asList("aaa", "hello", 1L)), rows);
}
}
use of com.apple.foundationdb.Range 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();
}
use of com.apple.foundationdb.Range in project fdb-record-layer by FoundationDB.
the class FDBRecordStore method addRecordReadConflict.
@Override
public void addRecordReadConflict(@Nonnull Tuple primaryKey) {
final Range recordRange = getRangeForRecord(primaryKey);
ensureContextActive().addReadConflictRange(recordRange.begin, recordRange.end);
}
use of com.apple.foundationdb.Range in project fdb-record-layer by FoundationDB.
the class FDBRecordStore method addRecordWriteConflict.
@Override
public void addRecordWriteConflict(@Nonnull Tuple primaryKey) {
final Range recordRange = getRangeForRecord(primaryKey);
ensureContextActive().addWriteConflictRange(recordRange.begin, recordRange.end);
}
Aggregations