Search in sources :

Example 21 with FDBRecordVersion

use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.

the class VersionIndexTest method saveLoadWithFunctionVersion.

@ParameterizedTest(name = "saveLoadWithFunctionVersion [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
@SuppressWarnings("try")
public void saveLoadWithFunctionVersion(int testFormatVersion, boolean testSplitLongRecords) throws ExecutionException, InterruptedException {
    formatVersion = testFormatVersion;
    splitLongRecords = testSplitLongRecords;
    MySimpleRecord recordCommitWithDummy = MySimpleRecord.newBuilder().setRecNo(43L).setNumValue2(43).build();
    MySimpleRecord recordManualWithDummy = MySimpleRecord.newBuilder().setRecNo(871L).setNumValue2(871).build();
    MySimpleRecord recordCommitWithoutDummy = MySimpleRecord.newBuilder().setRecNo(1415L).setNumValue2(1415).build();
    MySimpleRecord recordManualWithoutDummy = MySimpleRecord.newBuilder().setRecNo(1707L).setNumValue2(1707).build();
    FDBRecordVersion manualVersion;
    byte[] versionstamp;
    try (FDBRecordContext context = openContext(functionVersionHook)) {
        long readVersion = context.getReadVersion();
        manualVersion = FDBRecordVersion.firstInDBVersion(readVersion);
        FDBStoredRecord<Message> storedCommitWithDummy = recordStore.saveRecord(recordCommitWithDummy);
        assertEquals(FDBRecordVersion.incomplete(0), storedCommitWithDummy.getVersion());
        FDBStoredRecord<Message> storedManualWithDummy = recordStore.saveRecord(recordManualWithDummy, manualVersion);
        assertEquals(manualVersion, storedManualWithDummy.getVersion());
        FDBStoredRecord<Message> storedCommitWithoutDummy = recordStore.saveRecord(recordCommitWithoutDummy);
        assertEquals(FDBRecordVersion.incomplete(1), storedCommitWithoutDummy.getVersion());
        FDBStoredRecord<Message> storedManualWithoutDummy = recordStore.saveRecord(recordManualWithoutDummy, manualVersion);
        assertEquals(manualVersion, storedManualWithoutDummy.getVersion());
        context.commit();
        versionstamp = context.getVersionStamp();
        assertNotNull(versionstamp);
    }
    try (FDBRecordContext context = openContext(functionVersionHook)) {
        // Scan the functional index
        List<Tuple> indexKeys = recordStore.scanIndex(metaData.getIndex("MySimpleRecord$maybeVersion"), IndexScanType.BY_VALUE, TupleRange.ALL, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().get();
        List<Tuple> expectedKeys = Arrays.asList(Tuple.from(FDBRecordVersion.MIN_VERSION.toVersionstamp(), 43L), Tuple.from(FDBRecordVersion.MIN_VERSION.toVersionstamp(), 871L), Tuple.from(manualVersion.toVersionstamp(), 1707L), Tuple.from(Versionstamp.complete(versionstamp, 1), 1415L));
        assertEquals(expectedKeys, indexKeys);
    }
}
Also used : MySimpleRecord(com.apple.foundationdb.record.TestRecords1Proto.MySimpleRecord) Message(com.google.protobuf.Message) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) IndexEntry(com.apple.foundationdb.record.IndexEntry) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion) Tuple(com.apple.foundationdb.tuple.Tuple) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 22 with FDBRecordVersion

use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.

the class VersionIndexTest method versionststampSaveBehavior.

@SuppressWarnings("try")
private void versionststampSaveBehavior(RecordMetaDataHook hook) {
    System.out.printf("format version = %d ; splitLongRecords = %s%n", formatVersion, splitLongRecords);
    Map<Tuple, Optional<FDBRecordVersion>> storedVersions = new HashMap<>();
    byte[] commitVersion;
    try (FDBRecordContext context = openContext(hook)) {
        // Try saving with a null version
        FDBRecordVersion version1 = saveRecordAndRecordVersion(storedVersions, 1066L, null, FDBRecordStoreBase.VersionstampSaveBehavior.DEFAULT);
        if (recordStore.getRecordMetaData().isStoreRecordVersions()) {
            assertNotNull(version1);
        } else {
            assertNull(version1);
        }
        assertNull(saveRecordAndRecordVersion(storedVersions, 1215L, null, FDBRecordStoreBase.VersionstampSaveBehavior.NO_VERSION));
        assertNotNull(saveRecordAndRecordVersion(storedVersions, 1415L, null, FDBRecordStoreBase.VersionstampSaveBehavior.WITH_VERSION));
        assertNull(saveRecordAndRecordVersion(storedVersions, 800L, null, FDBRecordStoreBase.VersionstampSaveBehavior.IF_PRESENT));
        // Try saving with a non-null version
        FDBRecordVersion nonNullVersion = FDBRecordVersion.firstInDBVersion(context.getReadVersion());
        assertEquals(nonNullVersion, saveRecordAndRecordVersion(storedVersions, 1564L, nonNullVersion, FDBRecordStoreBase.VersionstampSaveBehavior.DEFAULT));
        assertThrows(RecordCoreException.class, () -> saveRecordAndRecordVersion(storedVersions, 10, nonNullVersion, FDBRecordStoreBase.VersionstampSaveBehavior.NO_VERSION));
        assertEquals(nonNullVersion, saveRecordAndRecordVersion(storedVersions, 1818L, nonNullVersion, FDBRecordStoreBase.VersionstampSaveBehavior.WITH_VERSION));
        assertEquals(nonNullVersion, saveRecordAndRecordVersion(storedVersions, 191, nonNullVersion, FDBRecordStoreBase.VersionstampSaveBehavior.IF_PRESENT));
        context.commit();
        commitVersion = context.getVersionStamp();
    }
    // See: https://github.com/FoundationDB/fdb-record-layer/issues/964
    if (metaData.isStoreRecordVersions() || formatVersion >= FDBRecordStore.SAVE_VERSION_WITH_RECORD_FORMAT_VERSION) {
        try (FDBRecordContext context = openContext(hook)) {
            for (Map.Entry<Tuple, Optional<FDBRecordVersion>> entry : storedVersions.entrySet()) {
                final Optional<FDBRecordVersion> completeVersionOptional = entry.getValue().map(version -> version.isComplete() ? version : version.withCommittedVersion(commitVersion));
                assertEquals(completeVersionOptional, recordStore.loadRecordVersion(entry.getKey()), "unexpected version for record with key " + entry.getKey());
                final FDBStoredRecord<?> record = recordStore.loadRecord(entry.getKey());
                assertEquals(completeVersionOptional.orElse(null), record == null ? null : record.getVersion(), "version mismatch loading record with key " + entry.getKey());
            }
            context.commit();
        }
    }
}
Also used : Optional(java.util.Optional) HashMap(java.util.HashMap) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) Tuple(com.apple.foundationdb.tuple.Tuple) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion)

Example 23 with FDBRecordVersion

use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.

the class VersionIndexTest method updateRecordInTwoStores.

@ParameterizedTest(name = "updateRecordInTwoStores [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
@SuppressWarnings("try")
public void updateRecordInTwoStores(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;
    final FDBRecordVersion version2;
    try (FDBRecordContext context = openContext(simpleVersionHook)) {
        final FDBRecordStore recordStore2 = recordStore.asBuilder().setSubspace(subspace2).open();
        // Update each record (just by saving with a new version)
        FDBStoredRecord<?> storedRecord1 = recordStore.saveRecord(record1);
        assertNotNull(storedRecord1.getVersion());
        assertFalse(storedRecord1.getVersion().isComplete());
        FDBStoredRecord<?> storedRecord2 = recordStore2.saveRecord(record2);
        assertNotNull(storedRecord2.getVersion());
        assertFalse(storedRecord2.getVersion().isComplete());
        assertThat(storedRecord2.getVersion(), greaterThan(storedRecord1.getVersion()));
        context.commit();
        assertNotNull(context.getVersionStamp());
        version1 = storedRecord1.getVersion().withCommittedVersion(context.getVersionStamp());
        version2 = storedRecord2.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());
        FDBStoredRecord<?> storedRecord2 = recordStore2.loadRecord(Tuple.from(record2.getRecNo()));
        assertNotNull(storedRecord2);
        assertEquals(version2, storedRecord2.getVersion());
    }
}
Also used : MySimpleRecord(com.apple.foundationdb.record.TestRecords1Proto.MySimpleRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 24 with FDBRecordVersion

use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.

the class VersionIndexTest method maxEverVersion.

@ParameterizedTest(name = "maxEverVersion [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
public void maxEverVersion(int testFormatVersion, boolean testSplitLongRecords) {
    formatVersion = testFormatVersion;
    splitLongRecords = testSplitLongRecords;
    // Add two records and record what should be the maximum version
    final FDBRecordVersion expectedMaxVersion;
    try (FDBRecordContext context = openContext(maxEverVersionHook)) {
        MySimpleRecord record1 = MySimpleRecord.newBuilder().setRecNo(1066L).build();
        recordStore.saveRecord(record1);
        MySimpleRecord record2 = MySimpleRecord.newBuilder().setRecNo(1776L).build();
        FDBStoredRecord<?> storedRecord2 = recordStore.saveRecord(record2);
        assertNotNull(storedRecord2.getVersion());
        context.commit();
        assertNotNull(context.getVersionStamp());
        expectedMaxVersion = storedRecord2.getVersion().withCommittedVersion(context.getVersionStamp());
    }
    assertMaxVersion(expectedMaxVersion);
    // Add a record with a version that is less than the current max
    FDBRecordVersion version3 = getSmallerVersion(expectedMaxVersion);
    assertThat(version3, lessThan(expectedMaxVersion));
    try (FDBRecordContext context = openContext(maxEverVersionHook)) {
        MySimpleRecord record3 = MySimpleRecord.newBuilder().setRecNo(1415L).build();
        recordStore.saveRecord(record3, version3);
        context.commit();
    }
    assertMaxVersion(expectedMaxVersion);
    // Delete the record with the current max
    try (FDBRecordContext context = openContext(maxEverVersionHook)) {
        FDBRecord<Message> loadedRecord = recordStore.loadRecord(Tuple.from(1776L));
        assertNotNull(loadedRecord);
        assertEquals(expectedMaxVersion, loadedRecord.getVersion());
        recordStore.deleteRecord(loadedRecord.getPrimaryKey());
        context.commit();
    }
    assertMaxVersion(expectedMaxVersion);
    // Add a record with a version that is higher than the current max
    FDBRecordVersion version4 = getBiggerVersion(expectedMaxVersion);
    assertThat(version4, greaterThan(expectedMaxVersion));
    try (FDBRecordContext context = openContext(maxEverVersionHook)) {
        MySimpleRecord record4 = MySimpleRecord.newBuilder().setRecNo(1863L).build();
        recordStore.saveRecord(record4, version4);
        context.commit();
    }
    assertMaxVersion(version4);
}
Also used : MySimpleRecord(com.apple.foundationdb.record.TestRecords1Proto.MySimpleRecord) Message(com.google.protobuf.Message) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 25 with FDBRecordVersion

use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion in project fdb-record-layer by FoundationDB.

the class VersionIndexTest method saveSameRecordTwoStores.

/**
 * Store two records with the same primary key in two record stores. Each one should get its own version.
 * This validates that the local version cache is per-record-store.
 */
@ParameterizedTest(name = "saveSameRecordTwoStores [formatVersion = {0}, splitLongRecords = {1}]")
@MethodSource("formatVersionArguments")
@SuppressWarnings("try")
public void saveSameRecordTwoStores(int testFormatVersion, boolean testSplitLongRecords) {
    formatVersion = testFormatVersion;
    splitLongRecords = testSplitLongRecords;
    final MySimpleRecord record1 = MySimpleRecord.newBuilder().setRecNo(1066).setNumValue2(42).build();
    final MySimpleRecord record2 = MySimpleRecord.newBuilder().setRecNo(1066).setNumValue2(1729).build();
    final FDBRecordVersion version1;
    final FDBRecordVersion version2;
    try (FDBRecordContext context = openContext(simpleVersionHook)) {
        final FDBRecordStore recordStore2 = recordStore.asBuilder().setSubspace(subspace2).create();
        FDBStoredRecord<?> storedRecord1 = recordStore.saveRecord(record1);
        assertNotNull(storedRecord1.getVersion());
        assertFalse(storedRecord1.getVersion().isComplete());
        assertNull(recordStore2.loadRecord(Tuple.from(record1.getRecNo())));
        FDBStoredRecord<?> storedRecord2 = recordStore2.saveRecord(record2);
        assertNotNull(storedRecord2.getVersion());
        assertFalse(storedRecord2.getVersion().isComplete());
        assertThat(storedRecord2.getVersion(), greaterThan(storedRecord1.getVersion()));
        context.commit();
        assertNotNull(context.getVersionStamp());
        version1 = storedRecord1.getVersion().withCommittedVersion(context.getVersionStamp());
        version2 = storedRecord2.getVersion().withCommittedVersion(context.getVersionStamp());
    }
    // Validate that the right versions are associated with the right records
    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());
        assertEquals(record1, storedRecord1.getRecord());
        FDBStoredRecord<?> storedRecord2 = recordStore2.loadRecord(Tuple.from(record2.getRecNo()));
        assertNotNull(storedRecord2);
        assertEquals(version2, storedRecord2.getVersion());
        assertEquals(record2, storedRecord2.getRecord());
    }
}
Also used : MySimpleRecord(com.apple.foundationdb.record.TestRecords1Proto.MySimpleRecord) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) FDBRecordVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Aggregations

FDBRecordVersion (com.apple.foundationdb.record.provider.foundationdb.FDBRecordVersion)25 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)23 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)21 MethodSource (org.junit.jupiter.params.provider.MethodSource)21 MySimpleRecord (com.apple.foundationdb.record.TestRecords1Proto.MySimpleRecord)20 Message (com.google.protobuf.Message)13 FDBRecordStore (com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore)10 Tuple (com.apple.foundationdb.tuple.Tuple)9 TreeMap (java.util.TreeMap)9 IndexEntry (com.apple.foundationdb.record.IndexEntry)8 TestRecords1Proto (com.apple.foundationdb.record.TestRecords1Proto)8 Index (com.apple.foundationdb.record.metadata.Index)8 HashMap (java.util.HashMap)8 Map (java.util.Map)8 SortedMap (java.util.SortedMap)8 PlanHashable (com.apple.foundationdb.record.PlanHashable)7 RecordCursorIterator (com.apple.foundationdb.record.RecordCursorIterator)7 IndexTypes (com.apple.foundationdb.record.metadata.IndexTypes)7 Tags (com.apple.test.Tags)6 Arrays (java.util.Arrays)6