Search in sources :

Example 21 with FDBStoreTimer

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

the class LocatableResolverTest method testDirectoryCache.

@Test
public void testDirectoryCache() {
    FDBDatabaseFactory factory = FDBDatabaseFactory.instance();
    factory.setDirectoryCacheSize(10);
    FDBStoreTimer timer = new FDBStoreTimer();
    FDBDatabase fdb = factory.getDatabase();
    // Make sure cache is fresh.
    fdb.close();
    String key = "world";
    Long value;
    try (FDBRecordContext context = fdb.openContext()) {
        context.setTimer(timer);
        value = context.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, globalScope.resolve(context.getTimer(), key));
    }
    int initialReads = timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ);
    assertThat(initialReads, is(greaterThanOrEqualTo(1)));
    for (int i = 0; i < 10; i++) {
        try (FDBRecordContext context = fdb.openContext()) {
            context.setTimer(timer);
            assertThat("we continue to resolve the same value", context.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, globalScope.resolve(context.getTimer(), key)), is(value));
        }
    }
    assertEquals(timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ), initialReads);
}
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) FDBDatabaseFactory(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 22 with FDBStoreTimer

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

the class LocatableResolverTest method testVersionIncrementInvalidatesCache.

@Test
public void testVersionIncrementInvalidatesCache() {
    FDBDatabaseFactory factory = FDBDatabaseFactory.instance();
    factory.setDirectoryCacheSize(10);
    FDBStoreTimer timer = new FDBStoreTimer();
    FDBDatabase fdb = factory.getDatabase();
    // Make sure cache is fresh, and resets version
    fdb.close();
    fdb.setResolverStateRefreshTimeMillis(100);
    String key = "some-key";
    Long value;
    try (FDBRecordContext context = fdb.openContext()) {
        context.setTimer(timer);
        value = context.asyncToSync(FDBStoreTimer.Waits.WAIT_DIRECTORY_RESOLVE, globalScope.resolve(context.getTimer(), key));
    }
    assertThat(timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ), is(greaterThanOrEqualTo(1)));
    timer.reset();
    consistently("we hit the cached value", () -> {
        try (FDBRecordContext context = fdb.openContext()) {
            context.setTimer(timer);
            assertThat("the resolved value is still the same", globalScope.resolve(context.getTimer(), key).join(), is(value));
        }
        return timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ);
    }, is(0), 200, 10);
    globalScope.incrementVersion().join();
    timer.reset();
    eventually("we see the version change and invalidate the cache", () -> {
        try (FDBRecordContext context = fdb.openContext()) {
            context.setTimer(timer);
            assertThat("the resolved value is still the same", globalScope.resolve(context.getTimer(), key).join(), is(value));
        }
        return timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ);
    }, is(1), 120, 10);
    timer.reset();
    consistently("the value is cached while the version is not changed", () -> {
        try (FDBRecordContext context = fdb.openContext()) {
            context.setTimer(timer);
            assertThat("the resolved value is still the same", globalScope.resolve(context.getTimer(), key).join(), is(value));
        }
        return timer.getCount(FDBStoreTimer.Events.DIRECTORY_READ);
    }, is(0), 200, 10);
}
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) FDBDatabaseFactory(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseFactory) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 23 with FDBStoreTimer

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

the class LocatableResolverTest method testCachingPerDbPerResolver.

@Test
public void testCachingPerDbPerResolver() {
    KeySpace keySpace = new KeySpace(new KeySpaceDirectory("resolver1", KeyType.STRING, "resolver1"), new KeySpaceDirectory("resolver2", KeyType.STRING, "resolver2"));
    LocatableResolver resolver1;
    LocatableResolver resolver2;
    FDBStoreTimer timer = new FDBStoreTimer();
    try (FDBRecordContext context = database.openContext()) {
        resolver1 = resolverFactory.create(keySpace.path("resolver1").toResolvedPath(context));
        resolver2 = resolverFactory.create(keySpace.path("resolver2").toResolvedPath(context));
        context.setTimer(timer);
        for (int i = 0; i < 10; i++) {
            resolver1.getVersion(context.getTimer()).join();
        }
        assertThat("We only read the value once", timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ), is(1));
        timer = new FDBStoreTimer();
        assertThat("count is reset", timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ), is(0));
        context.setTimer(timer);
        resolver2.getVersion(context.getTimer()).join();
        assertThat("We have to read the value for the new resolver", timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ), is(1));
        LocatableResolver newResolver1 = resolverFactory.create(keySpace.path("resolver1").toResolvedPath(context));
        timer = new FDBStoreTimer();
        assertThat("count is reset", timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ), is(0));
        context.setTimer(timer);
        for (int i = 0; i < 10; i++) {
            newResolver1.getVersion(context.getTimer()).join();
        }
        assertThat("we still hit the cache", timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ), is(0));
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 24 with FDBStoreTimer

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

the class LocatableResolverTest method testWriteLockCaching.

@Test
public void testWriteLockCaching() {
    FDBStoreTimer timer = new FDBStoreTimer();
    try (FDBRecordContext context = database.openContext()) {
        context.setTimer(timer);
        globalScope.resolve(context.getTimer(), "something").join();
        int initialCount = timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ);
        assertThat("first read must check the lock in the database", initialCount, greaterThanOrEqualTo(1));
        timer.reset();
        int oldCount = timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ);
        for (int i = 0; i < 10; i++) {
            globalScope.resolve(context.getTimer(), "something-" + i).join();
            // depending on the nature of the write safety check we may need to read the key multiple times
            // so assert that we do at least one read on each resolve
            int currentCount = timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ);
            assertThat("subsequent writes must also check the key", currentCount, is(greaterThan(oldCount)));
            oldCount = currentCount;
        }
        timer.reset();
        for (int i = 0; i < 10; i++) {
            globalScope.resolve(context.getTimer(), "something-" + i).join();
        }
        assertThat("reads do not need to check the key", timer.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ), is(0));
    }
    FDBDatabaseFactory.instance().clear();
    FDBDatabase newDatabase = FDBDatabaseFactory.instance().getDatabase();
    FDBStoreTimer timer2 = new FDBStoreTimer();
    try (FDBRecordContext context = newDatabase.openContext()) {
        context.setTimer(timer2);
        globalScope.resolve(context.getTimer(), "something").join();
        assertThat("state is loaded from the new database", timer2.getCount(FDBStoreTimer.DetailEvents.RESOLVER_STATE_READ), is(1));
    }
}
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 25 with FDBStoreTimer

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

the class FDBRecordStoreStateCacheTest method storeDeletionAcrossContexts.

/**
 * After a store is deleted, validate that future transactions need to reload it from cache.
 */
@ParameterizedTest(name = "storeDeletionAcrossContexts (test context = {0})")
@MethodSource("testContextSource")
public void storeDeletionAcrossContexts(@Nonnull StateCacheTestContext testContext) throws Exception {
    FDBRecordStoreStateCache storeStateCache = fdb.getStoreStateCache();
    try {
        fdb.setStoreStateCache(testContext.getCache(fdb));
        FDBRecordStore.Builder storeBuilder;
        try (FDBRecordContext context = openContext()) {
            openSimpleRecordStore(context);
            assertTrue(recordStore.setStateCacheability(true));
            storeBuilder = recordStore.asBuilder();
            commit(context);
        }
        // Delete by calling deleteStore.
        try (FDBRecordContext context = testContext.getCachedContext(fdb, storeBuilder, FDBRecordStoreBase.StoreExistenceCheck.ERROR_IF_NOT_EXISTS)) {
            openSimpleRecordStore(context);
            assertEquals(1, context.getTimer().getCount(FDBStoreTimer.Counts.STORE_STATE_CACHE_HIT));
            FDBRecordStore.deleteStore(context, recordStore.getSubspace());
            commit(context);
        }
        // After deleting it, when opening the same store again, it shouldn't be cached.
        try (FDBRecordContext context = fdb.openContext(null, new FDBStoreTimer())) {
            FDBRecordStore store = storeBuilder.setContext(context).create();
            assertEquals(1, context.getTimer().getCount(FDBStoreTimer.Counts.STORE_STATE_CACHE_MISS));
            assertTrue(store.setStateCacheability(true));
            commit(context);
        }
        // Delete by calling path.deleteAllData
        try (FDBRecordContext context = testContext.getCachedContext(fdb, storeBuilder, FDBRecordStoreBase.StoreExistenceCheck.ERROR_IF_NOT_EXISTS)) {
            openSimpleRecordStore(context);
            assertEquals(1, context.getTimer().getCount(FDBStoreTimer.Counts.STORE_STATE_CACHE_HIT));
            path.deleteAllData(context);
            commit(context);
        }
        try (FDBRecordContext context = fdb.openContext(null, new FDBStoreTimer())) {
            FDBRecordStore store = storeBuilder.setContext(context).create();
            store.setStateCacheabilityAsync(true).get();
            assertEquals(1, context.getTimer().getCount(FDBStoreTimer.Counts.STORE_STATE_CACHE_MISS));
            commit(context);
        }
        // Deleting all records should not disable the index state.
        final String disabledIndex = "MySimpleRecord$str_value_indexed";
        try (FDBRecordContext context = testContext.getCachedContext(fdb, storeBuilder, FDBRecordStoreBase.StoreExistenceCheck.ERROR_IF_NOT_EXISTS)) {
            openSimpleRecordStore(context);
            recordStore.markIndexDisabled(disabledIndex).get();
            commit(context);
        }
        try (FDBRecordContext context = testContext.getCachedContext(fdb, storeBuilder, FDBRecordStoreBase.StoreExistenceCheck.ERROR_IF_NOT_EXISTS)) {
            openSimpleRecordStore(context);
            assertTrue(recordStore.isIndexDisabled(disabledIndex));
            recordStore.deleteAllRecords();
            commit(context);
        }
        try (FDBRecordContext context = testContext.getCachedContext(fdb, storeBuilder, FDBRecordStoreBase.StoreExistenceCheck.ERROR_IF_NOT_EXISTS)) {
            openSimpleRecordStore(context);
            assertTrue(recordStore.isIndexDisabled(disabledIndex));
            commit(context);
        }
    } finally {
        fdb.setStoreStateCache(storeStateCache);
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) Matchers.containsString(org.hamcrest.Matchers.containsString) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Aggregations

FDBStoreTimer (com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer)29 Test (org.junit.jupiter.api.Test)21 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)15 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)14 FDBDatabase (com.apple.foundationdb.record.provider.foundationdb.FDBDatabase)9 Nonnull (javax.annotation.Nonnull)9 Arrays (java.util.Arrays)8 List (java.util.List)8 Function (java.util.function.Function)8 Collections (java.util.Collections)7 CompletableFuture (java.util.concurrent.CompletableFuture)7 Collectors (java.util.stream.Collectors)7 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)7 Assertions.assertFalse (org.junit.jupiter.api.Assertions.assertFalse)7 RecordCursor (com.apple.foundationdb.record.RecordCursor)6 FirableCursor (com.apple.foundationdb.record.cursors.FirableCursor)6 StoreTimer (com.apple.foundationdb.record.provider.common.StoreTimer)6 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)6 Iterator (java.util.Iterator)6 ExecutionException (java.util.concurrent.ExecutionException)6