Search in sources :

Example 6 with FDBDatabase

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

the class LocatableResolverTest method testCachesWinnerOfConflict.

@Test
public void testCachesWinnerOfConflict() {
    FDBDatabase fdb = FDBDatabaseFactory.instance().getDatabase();
    fdb.clearCaches();
    // In the scoped directory layer test, this can conflict with initializing the reverse directory layer
    fdb.getReverseDirectoryCache().waitUntilReadyForTesting();
    final String key = "hello " + UUID.randomUUID();
    long resolved;
    final FDBStoreTimer timer = new FDBStoreTimer();
    try (FDBRecordContext context1 = fdb.openContext(null, timer);
        FDBRecordContext context2 = fdb.openContext(null, timer)) {
        // Ensure both started
        context1.getReadVersion();
        context2.getReadVersion();
        // Both contexts try to create the key
        CompletableFuture<Long> resolvedFuture1 = globalScope.resolve(context1, key);
        CompletableFuture<Long> resolvedFuture2 = globalScope.resolve(context2, key);
        long resolved1 = context1.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, resolvedFuture1);
        long resolved2 = context2.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, resolvedFuture2);
        assertAll(() -> assertThat("two concurrent resolutions of the same key should match", resolved1, equalTo(resolved2)), () -> assertThat("at least one transaction should read from database", timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ), greaterThanOrEqualTo(1)), () -> assertThat("should not open more transactions than the two parents and five children", timer.getCount(FDBStoreTimer.Counts.OPEN_CONTEXT), lessThanOrEqualTo(7)), () -> assertThat("should not have committed more than the five children", timer.getCount(FDBStoreTimer.Events.COMMIT), lessThanOrEqualTo(5)));
        resolved = resolved1;
    }
    timer.reset();
    try (FDBRecordContext context = fdb.openContext(null, timer)) {
        context.getReadVersion();
        long resolvedAgain = context.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, globalScope.resolve(context, key));
        assertAll(() -> assertThat("resolved value in cache should match initial resolution", resolvedAgain, equalTo(resolved)), () -> assertThat("should have resolved from cache", timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ), equalTo(0)));
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 7 with FDBDatabase

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

the class LocatableResolverTest method testDoesNotCacheValueReadFromReadYourWritesCache.

/**
 * This is mainly to test a counter factual where the same transaction is used to actually resolve the value as
 * is used by the caller. In that case, one could accidentally pollute the cache with uncommitted data. To protect
 * against that, this test is designed to fail if someone changes the resolution logic so that uncommitted data
 * (even possibly uncommitted data re-read from the same transaction that wrote it) might be put in the cache.
 */
@Test
public void testDoesNotCacheValueReadFromReadYourWritesCache() {
    FDBDatabase fdb = FDBDatabaseFactory.instance().getDatabase();
    fdb.clearCaches();
    final String key = "hello " + UUID.randomUUID();
    final FDBStoreTimer timer = new FDBStoreTimer();
    long resolved;
    try (FDBRecordContext context = fdb.openContext(null, timer)) {
        // First time: nothing in cache or DB. Entry is created.
        resolved = context.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, globalScope.resolve(context, key));
        assertEquals(1, timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ), "should have read from the database");
        // Second time: if same context used to create and read, then this would read from transaction's read your writes cache, not the database
        long resolvedAgain = context.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, globalScope.resolve(context, key));
        assertEquals(resolved, resolvedAgain, "resolving the same key should not change the value even in the same transaction");
    // do not commit main transaction
    }
    // Read from cache. If present, this should not have changed its value
    timer.reset();
    boolean cached;
    try (FDBRecordContext context = fdb.openContext(null, timer)) {
        long resolvedFromCache = context.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, globalScope.resolve(context, key));
        cached = timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ) == 0;
        if (cached) {
            assertEquals(resolved, resolvedFromCache, "resolved value should have changed when reading from cache");
        }
    }
    // Clear caches, and re-read from the database.
    if (cached) {
        fdb.clearCaches();
        timer.reset();
        try (FDBRecordContext context = fdb.openContext(null, timer)) {
            long resolvedFromDb = context.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, globalScope.resolve(context, key));
            assertEquals(resolved, resolvedFromDb, "resolved value from database should have matched initial resolution");
        }
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 8 with FDBDatabase

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

the class KeySpaceDirectoryTest method rootForMetadataTests.

private KeySpace rootForMetadataTests(String name, ResolverCreateHooks hooks, Function<FDBRecordContext, CompletableFuture<LocatableResolver>> generator) {
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    KeySpace root = new KeySpace(new DirectoryLayerDirectory(name, name).addSubdirectory(new DirectoryLayerDirectory("dir_with_metadata_name", DirWithMetadataWrapper::new, generator, hooks)));
    database.run(context -> root.path(name).deleteAllDataAsync(context));
    return root;
}
Also used : FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase)

Example 9 with FDBDatabase

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

the class KeySpaceDirectoryTest method testDirectoryLayerDirectoryUsingLongs.

@Test
public void testDirectoryLayerDirectoryUsingLongs() throws Exception {
    KeySpace root = new KeySpace(new DirectoryLayerDirectory("cabinet", "cabinet").addSubdirectory(new DirectoryLayerDirectory("game")));
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    final Tuple senetTuple;
    final Tuple urTuple;
    try (FDBRecordContext context = database.openContext()) {
        senetTuple = root.path("cabinet").add("game", "senet").toTuple(context);
        urTuple = root.path("cabinet").add("game", "royal_game_of_ur").toTuple(context);
        context.commit();
    }
    try (FDBRecordContext context = database.openContext()) {
        // Verify that I can create the tuple again using the directory layer values.
        assertEquals(senetTuple, root.path("cabinet").add("game", senetTuple.getLong(1)).toTuple(context));
        assertEquals(urTuple, root.path("cabinet").add("game", urTuple.getLong(1)).toTuple(context));
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 10 with FDBDatabase

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

the class KeySpaceDirectoryTest method testListConstantValue.

@Test
public void testListConstantValue() throws Exception {
    // Create a root directory called "a" with subdirs of every type and a constant value
    Long rootValue = random.nextLong();
    KeySpaceDirectory dirA = new KeySpaceDirectory("a", KeyType.LONG, rootValue);
    for (KeyTypeValue kv : valueOfEveryType) {
        dirA.addSubdirectory(new KeySpaceDirectory(kv.keyType.toString(), kv.keyType, kv.generator.get()));
    }
    KeySpace root = new KeySpace(dirA);
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    try (FDBRecordContext context = database.openContext()) {
        Transaction tr = context.ensureActive();
        for (KeyTypeValue kv : valueOfEveryType) {
            KeySpaceDirectory dir = root.getDirectory("a").getSubdirectory(kv.keyType.name());
            for (int i = 0; i < 5; i++) {
                tr.set(Tuple.from(rootValue, dir.getValue(), i).pack(), Tuple.from(i).pack());
            }
        }
        context.commit();
    }
    try (FDBRecordContext context = database.openContext()) {
        for (KeyTypeValue kv : valueOfEveryType) {
            KeySpaceDirectory dir = root.getDirectory("a").getSubdirectory(kv.keyType.name());
            List<ResolvedKeySpacePath> paths = root.path("a").listSubdirectory(context, kv.keyType.toString());
            assertEquals(1, paths.size());
            if (dir.getKeyType() == KeyType.BYTES) {
                assertTrue(Arrays.equals((byte[]) dir.getValue(), paths.get(0).toTuple().getBytes(1)));
            } else {
                assertEquals(dir.getValue(), paths.get(0).toTuple().get(1));
            }
        }
    }
}
Also used : Transaction(com.apple.foundationdb.Transaction) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Test(org.junit.jupiter.api.Test)

Aggregations

FDBDatabase (com.apple.foundationdb.record.provider.foundationdb.FDBDatabase)42 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)39 Test (org.junit.jupiter.api.Test)38 Tuple (com.apple.foundationdb.tuple.Tuple)19 FDBStoreTimer (com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer)14 Transaction (com.apple.foundationdb.Transaction)12 FDBDatabaseFactory (com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory)11 ScanProperties (com.apple.foundationdb.record.ScanProperties)9 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)9 ArrayList (java.util.ArrayList)8 HashMap (java.util.HashMap)8 List (java.util.List)8 CompletableFuture (java.util.concurrent.CompletableFuture)8 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)8 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)7 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)7 RecordCoreArgumentException (com.apple.foundationdb.record.RecordCoreArgumentException)7 RecordCursor (com.apple.foundationdb.record.RecordCursor)7 FDBTestBase (com.apple.foundationdb.record.provider.foundationdb.FDBTestBase)7 Tags (com.apple.test.Tags)7