use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.
the class VersionIndexTest method queryOnRepeatedVersion.
@ParameterizedTest(name = "queryOnRepeatedVersions [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
@SuppressWarnings("try")
public void queryOnRepeatedVersion(int testFormatVersion, boolean testSplitLongRecords) {
formatVersion = testFormatVersion;
splitLongRecords = testSplitLongRecords;
List<MySimpleRecord> simpleRecords = IntStream.range(0, 30).mapToObj(id -> {
MySimpleRecord.Builder builder = MySimpleRecord.newBuilder().setRecNo(id * 2).setNumValue2(id % 2).setNumValue3Indexed(id % 3);
for (int i = 0; i < id % 3; i++) {
builder.addRepeater(i);
}
return builder.build();
}).collect(Collectors.toList());
Iterator<MySimpleRecord> simpleIterator = simpleRecords.iterator();
while (simpleIterator.hasNext()) {
try (FDBRecordContext context = openContext(repeatedVersionHook)) {
int done = 0;
while (simpleIterator.hasNext() && done != 5) {
recordStore.saveRecord(simpleIterator.next());
done += 1;
}
context.commit();
}
}
try (FDBRecordContext context = openContext(repeatedVersionHook)) {
List<Long> expectedKeys = simpleRecords.stream().filter(rec -> rec.getRepeaterList().contains(1)).map(MySimpleRecord::getRecNo).collect(Collectors.toList());
FDBRecordVersion last = null;
List<Long> receivedKeys = new ArrayList<>();
int totalSeen = 0;
while (true) {
RecordQueryPlan plan;
if (last == null) {
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.field("repeater").oneOfThem().equalsValue(1)).setSort(VersionKeyExpression.VERSION).setRemoveDuplicates(false).build();
plan = planner.plan(query);
assertEquals("Index(MySimpleRecord$repeater-version [[1],[1]])", plan.toString());
} else {
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("repeater").oneOfThem().equalsValue(1), Query.version().greaterThan(last))).setSort(VersionKeyExpression.VERSION).setRemoveDuplicates(false).build();
plan = planner.plan(query);
assertEquals("Index(MySimpleRecord$repeater-version ([1, " + last.toVersionstamp() + "],[1]])", plan.toString());
}
RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan, null, ExecuteProperties.newBuilder().setReturnedRowLimit(4).build()).asIterator();
boolean hasAny = false;
while (cursor.hasNext()) {
hasAny = true;
FDBQueriedRecord<Message> record = cursor.next();
assertTrue(record.hasVersion());
if (last != null) {
assertThat(last, lessThan(record.getVersion()));
}
last = record.getVersion();
MySimpleRecord simpleRecord = MySimpleRecord.newBuilder().mergeFrom(record.getRecord()).build();
assertThat(simpleRecord.getRepeaterList(), hasItem(1));
receivedKeys.add(field("rec_no").evaluateSingleton(record.getStoredRecord()).toTuple().getLong(0));
totalSeen += 1;
}
if (!hasAny) {
break;
}
}
assertEquals(simpleRecords.size() / 3, totalSeen);
assertEquals(expectedKeys, receivedKeys);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.
the class VersionIndexTest method validateUsingNewerVersionFormat.
private <M extends Message> void validateUsingNewerVersionFormat(@Nonnull List<FDBStoredRecord<M>> storedRecords) {
// Make sure the old keyspace doesn't have anything in it
final Subspace legacyVersionSubspace = recordStore.getLegacyVersionSubspace();
KeyValueCursor legacyKvs = KeyValueCursor.Builder.withSubspace(legacyVersionSubspace).setContext(recordStore.getRecordContext()).setScanProperties(ScanProperties.FORWARD_SCAN).build();
assertEquals(0, (int) legacyKvs.getCount().join());
// Look for the versions within the primary keyspace
final Subspace recordsSubspace = recordStore.recordsSubspace();
RecordCursorIterator<Pair<Tuple, FDBRecordVersion>> versionKeyPairs = KeyValueCursor.Builder.withSubspace(recordsSubspace).setContext(recordStore.getRecordContext()).setScanProperties(ScanProperties.FORWARD_SCAN).build().map(kv -> Pair.of(recordsSubspace.unpack(kv.getKey()), kv.getValue())).filter(tupleBytesPair -> tupleBytesPair.getLeft().getLong(tupleBytesPair.getLeft().size() - 1) == -1).map(tupleBytesPair -> Pair.of(tupleBytesPair.getLeft().popBack(), FDBRecordVersion.fromVersionstamp(Tuple.fromBytes(tupleBytesPair.getRight()).getVersionstamp(0)))).asIterator();
for (FDBStoredRecord<M> storedRecord : storedRecords) {
assertTrue(versionKeyPairs.hasNext());
Pair<Tuple, FDBRecordVersion> versionPair = versionKeyPairs.next();
assertEquals(storedRecord.getPrimaryKey(), versionPair.getLeft());
assertEquals(storedRecord.getVersion(), versionPair.getRight());
}
assertFalse(versionKeyPairs.hasNext());
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.
the class VersionIndexTest method deleteRecordInTwoStores.
@ParameterizedTest(name = "deleteRecordInTwoStores [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
@SuppressWarnings("try")
public void deleteRecordInTwoStores(int testFormatVersion, boolean testSplitLongRecords) {
formatVersion = testFormatVersion;
splitLongRecords = testSplitLongRecords;
final MySimpleRecord record1 = MySimpleRecord.newBuilder().setRecNo(1066L).setNumValue2(42).build();
final MySimpleRecord record2 = MySimpleRecord.newBuilder().setRecNo(1066L).setNumValue2(1729).build();
try (FDBRecordContext context = openContext(simpleVersionHook)) {
final FDBRecordStore recordStore2 = recordStore.asBuilder().setSubspace(subspace2).create();
// Store the records with a fake complete pseudo version to avoid potential problems
// tested in saveSameRecordInTwoStores
final FDBRecordVersion pseudoVersion = FDBRecordVersion.firstInDBVersion(context.getReadVersion());
recordStore.saveRecord(record1, FDBRecordVersion.complete(pseudoVersion.getGlobalVersion(), 1));
recordStore2.saveRecord(record2, FDBRecordVersion.complete(pseudoVersion.getGlobalVersion(), 2));
context.commit();
}
final FDBRecordVersion version1;
try (FDBRecordContext context = openContext(simpleVersionHook)) {
final FDBRecordStore recordStore2 = recordStore.asBuilder().setSubspace(subspace2).open();
// Change the version in one record store
FDBStoredRecord<?> storedRecord1 = recordStore.saveRecord(record1);
assertNotNull(storedRecord1.getVersion());
assertFalse(storedRecord1.getVersion().isComplete());
// Delete the record in the other record store
assertTrue(recordStore2.deleteRecord(Tuple.from(record2.getRecNo())));
context.commit();
assertNotNull(context.getVersionStamp());
version1 = storedRecord1.getVersion().withCommittedVersion(context.getVersionStamp());
}
try (FDBRecordContext context = openContext(simpleVersionHook)) {
final FDBRecordStore recordStore2 = recordStore.asBuilder().setSubspace(subspace2).open();
FDBStoredRecord<?> storedRecord1 = recordStore.loadRecord(Tuple.from(record1.getRecNo()));
assertNotNull(storedRecord1);
assertEquals(version1, storedRecord1.getVersion());
assertNull(recordStore2.loadRecord(Tuple.from(record2.getRecNo())));
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.
the class VersionIndexTest method assertMaxVersionsForGroups.
private void assertMaxVersionsForGroups(@Nonnull Object... keyValue) {
if (keyValue.length % 2 != 0) {
throw new RecordCoreArgumentException("expected an even number of keys and values for grouping");
}
TreeMap<Integer, FDBRecordVersion> groupsToVersions = new TreeMap<>();
for (int i = 0; i < keyValue.length; i += 2) {
Integer group = (Integer) keyValue[i];
FDBRecordVersion version = (FDBRecordVersion) keyValue[i + 1];
groupsToVersions.put(group, version);
}
assertMaxVersionsForGroups(groupsToVersions);
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.
the class VersionIndexTest method maxEverVersionWithFunction.
@ParameterizedTest(name = "maxEverVersionWithFunction [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
public void maxEverVersionWithFunction(int testFormatVersion, boolean testSplitLongRecords) {
formatVersion = testFormatVersion;
splitLongRecords = testSplitLongRecords;
// Add a record with a fake version
FDBRecordVersion expectedMaxVersion;
try (FDBRecordContext context = openContext(maxEverVersionWithFunctionHook)) {
MySimpleRecord record = MySimpleRecord.newBuilder().setRecNo(1066).setNumValue2(0).setNumValue3Indexed(1066).build();
recordStore.saveRecord(record);
context.commit();
expectedMaxVersion = FDBRecordVersion.firstInDBVersion(1066);
}
assertMaxVersionWithFunction(0, expectedMaxVersion);
// Add a record with a fake version but the version is smaller, so the max index shouldn't update
try (FDBRecordContext context = openContext(maxEverVersionWithFunctionHook)) {
MySimpleRecord record = MySimpleRecord.newBuilder().setRecNo(800L).setNumValue2(0).setNumValue3Indexed(800).build();
recordStore.saveRecord(record);
context.commit();
}
assertMaxVersionWithFunction(0, expectedMaxVersion);
// Add a record where the version information is taken from the record's version
try (FDBRecordContext context = openContext(maxEverVersionWithFunctionHook)) {
MySimpleRecord record = MySimpleRecord.newBuilder().setRecNo(1415L).setNumValue2(2).setNumValue3Indexed(1836).build();
expectedMaxVersion = FDBRecordVersion.firstInDBVersion(800L);
recordStore.saveRecord(record, expectedMaxVersion);
context.commit();
}
assertMaxVersionWithFunction(2, expectedMaxVersion);
// Control column does not go backwards if the version is complete
try (FDBRecordContext context = openContext(maxEverVersionWithFunctionHook)) {
MySimpleRecord record = MySimpleRecord.newBuilder().setRecNo(1863L).setNumValue2(1).setNumValue3Indexed(1455).build();
recordStore.saveRecord(record, FDBRecordVersion.firstInDBVersion(1776));
context.commit();
}
assertMaxVersionWithFunction(2, expectedMaxVersion);
// Control column can go backwards with an incomplete version
try (FDBRecordContext context = openContext(maxEverVersionWithFunctionHook)) {
MySimpleRecord record = MySimpleRecord.newBuilder().setRecNo(1215L).setNumValue2(1).setNumValue3Indexed(70).build();
recordStore.saveRecord(record);
context.commit();
assertNotNull(context.getVersionStamp());
expectedMaxVersion = FDBRecordVersion.complete(context.getVersionStamp(), 0);
}
assertMaxVersionWithFunction(1, expectedMaxVersion);
// Won't go backwards if the control column is the "choose a fake version" value
try (FDBRecordContext context = openContext(maxEverVersionWithFunctionHook)) {
MySimpleRecord record = MySimpleRecord.newBuilder().setRecNo(1485L).setNumValue2(0).setNumValue3Indexed(1707).build();
recordStore.saveRecord(record);
context.commit();
}
assertMaxVersionWithFunction(1, expectedMaxVersion);
}
Aggregations