Search in sources :

Example 21 with FDBDatabase

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

the class KeySpaceDirectoryTest method testPathWrapperExample.

/*
     * This isn't specifically just a test, but is also here to demonstrate how you can use the KeySpacePath
     * wrapping facility to work with paths in a type safe manner.
     */
@Test
public void testPathWrapperExample() throws Exception {
    EnvironmentKeySpace keySpace = new EnvironmentKeySpace("production");
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    // Create a tuple to represent a path to a user's main store. This will trigger the creation of the
    // necessary directory layer entries.
    final Tuple dataStoreTuple;
    final Tuple metadataStoreTuple;
    try (FDBRecordContext context = database.openContext()) {
        ApplicationPath application = keySpace.root().userid(123).application("myApplication");
        dataStoreTuple = application.dataStore().toTuple(context);
        metadataStoreTuple = application.metadataStore().toTuple(context);
        context.commit();
    }
    try (FDBRecordContext context = database.openContext()) {
        List<Long> entries = resolveBatch(context, keySpace.getRootName(), "myApplication");
        // Validate the entries created above look like what we expect
        assertEquals(Tuple.from(entries.get(0), 123L, entries.get(1), EnvironmentKeySpace.DATA_VALUE), dataStoreTuple);
        assertEquals(Tuple.from(entries.get(0), 123L, entries.get(1), EnvironmentKeySpace.METADATA_VALUE), metadataStoreTuple);
        ResolvedKeySpacePath path = keySpace.fromKey(context, dataStoreTuple);
        assertThat(path.toPath(), instanceOf(DataPath.class));
        DataPath mainStorePath = (DataPath) path.toPath();
        assertEquals(EnvironmentKeySpace.DATA_VALUE, mainStorePath.getValue());
        assertEquals(EnvironmentKeySpace.DATA_VALUE, mainStorePath.resolveAsync(context).get().getResolvedValue());
        assertEquals(entries.get(1), mainStorePath.parent().resolveAsync(context).get().getResolvedValue());
        assertEquals("myApplication", mainStorePath.parent().getValue());
        assertEquals(123L, mainStorePath.parent().parent().getValue());
        assertEquals(entries.get(0), mainStorePath.parent().parent().parent().resolveAsync(context).get().getResolvedValue());
        assertEquals("production", mainStorePath.parent().parent().parent().getValue());
        assertEquals(null, mainStorePath.parent().parent().parent().parent());
        assertThat(keySpace.fromKey(context, TupleHelpers.subTuple(dataStoreTuple, 0, 1)).toPath(), instanceOf(EnvironmentRoot.class));
        assertThat(keySpace.fromKey(context, TupleHelpers.subTuple(dataStoreTuple, 0, 2)).toPath(), instanceOf(UserPath.class));
        assertThat(keySpace.fromKey(context, TupleHelpers.subTuple(dataStoreTuple, 0, 3)).toPath(), instanceOf(ApplicationPath.class));
        path = keySpace.fromKey(context, metadataStoreTuple);
        assertThat(path.toPath(), instanceOf(MetadataPath.class));
        MetadataPath metadataPath = (MetadataPath) path.toPath();
        assertEquals(EnvironmentKeySpace.METADATA_VALUE, metadataPath.getValue());
        assertEquals(EnvironmentKeySpace.METADATA_VALUE, metadataPath.resolveAsync(context).get().getResolvedValue());
        assertEquals(entries.get(1), metadataPath.parent().resolveAsync(context).get().getResolvedValue());
        assertEquals("myApplication", metadataPath.parent().getValue());
        assertEquals(123L, metadataPath.parent().parent().getValue());
        assertEquals(entries.get(0), metadataPath.parent().parent().parent().resolveAsync(context).get().getResolvedValue());
        assertEquals("production", metadataPath.parent().parent().parent().getValue());
        assertEquals(null, metadataPath.parent().parent().parent().parent());
        assertThat(keySpace.fromKey(context, TupleHelpers.subTuple(dataStoreTuple, 0, 1)).toPath(), instanceOf(EnvironmentRoot.class));
        assertThat(keySpace.fromKey(context, TupleHelpers.subTuple(dataStoreTuple, 0, 2)).toPath(), instanceOf(UserPath.class));
        assertThat(keySpace.fromKey(context, TupleHelpers.subTuple(dataStoreTuple, 0, 3)).toPath(), instanceOf(ApplicationPath.class));
        // Create a fake main store "record" key to demonstrate that we can get the key as the remainder
        // 1=record space, record id, 0=unsplit record
        Tuple recordTuple = dataStoreTuple.add(1L).add("someStr").add(0L);
        path = keySpace.fromKey(context, recordTuple);
        assertThat(path.toPath(), instanceOf(DataPath.class));
        assertEquals(Tuple.from(1L, "someStr", 0L), path.getRemainder());
        assertEquals(dataStoreTuple, path.toTuple());
    }
}
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 22 with FDBDatabase

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

the class KeySpaceDirectoryTest method testListDoesNotGoTooDeep.

@Test
public void testListDoesNotGoTooDeep() throws Exception {
    KeySpace root = new KeySpace(new KeySpaceDirectory("a", KeyType.LONG, random.nextLong()).addSubdirectory(new DirectoryLayerDirectory("b").addSubdirectory(new KeySpaceDirectory("c", KeyType.STRING).addSubdirectory(new KeySpaceDirectory("d", KeyType.BYTES).addSubdirectory(new KeySpaceDirectory("e", KeyType.LONG))))));
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    try (FDBRecordContext context = database.openContext()) {
        Transaction tr = context.ensureActive();
        for (int i = 0; i < 5; i++) {
            tr.set(root.path("a").add("b", "foo_" + i).add("c", "hi_" + i).add("d", new byte[] { (byte) i }).toTuple(context).pack(), Tuple.from(i).pack());
        }
        context.commit();
    }
    // remainder on the "b" path entry.
    try (FDBRecordContext context = database.openContext()) {
        List<ResolvedKeySpacePath> paths;
        // Check listing from the root
        paths = root.listDirectory(context, "a");
        assertThat("Number of paths in 'a'", paths.size(), is(1));
        assertThat("Value of subdirectory 'a'", paths.get(0).getLogicalValue(), is(root.getDirectory("a").getValue()));
        assertThat("Remainder size of 'a'", paths.get(0).getRemainder().size(), is(3));
        // List from "b"
        paths = root.path("a").listSubdirectory(context, "b");
        assertThat("Number of paths in 'b'", paths.size(), is(5));
        for (ResolvedKeySpacePath path : paths) {
            assertThat("Listing of 'b' directory", path.getDirectoryName(), is("b"));
            Tuple remainder = path.getRemainder();
            assertThat("Remainder of 'b'", remainder.size(), is(2));
            assertThat("Remainder of 'b', first tuple value", remainder.getString(0), startsWith("hi_"));
            assertThat("Remainder of 'b', second tuple value", remainder.getBytes(1), instanceOf(new byte[0].getClass()));
        }
        // List from "c"
        paths = root.path("a").add("b", "foo_0").listSubdirectory(context, "c");
        assertThat("Number of paths in 'c'", paths.size(), is(1));
        for (ResolvedKeySpacePath path : paths) {
            assertThat("Listing of 'c' directory", path.getDirectoryName(), is("c"));
            final Tuple remainder = path.getRemainder();
            assertThat("Remainder of 'c'", remainder.size(), is(1));
            assertThat("Remainder of 'c', first tuple value", remainder.getBytes(0), instanceOf(new byte[0].getClass()));
        }
        // List from "d"
        paths = root.path("a").add("b", "foo_0").add("c", "hi_0").listSubdirectory(context, "d");
        assertThat("Number of paths in 'd'", paths.size(), is(1));
        ResolvedKeySpacePath path = paths.get(0);
        assertThat("Remainder of 'd'", path.getRemainder(), is((Tuple) null));
        // List from "e" (which has no data)
        paths = root.path("a").add("b", "foo_0").add("c", "hi_0").add("d", new byte[] { 0x00 }).listSubdirectory(context, "e");
        assertThat("Number of paths in 'e'", paths.size(), is(0));
    }
}
Also used : Transaction(com.apple.foundationdb.Transaction) 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 23 with FDBDatabase

use of com.apple.foundationdb.record.provider.foundationdb.FDBDatabase 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 24 with FDBDatabase

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

the class KeySpaceDirectoryTest method testAllTypesConstValues.

@Test
public void testAllTypesConstValues() throws Exception {
    KeySpaceDirectory rootDir = new KeySpaceDirectory("root", KeyType.LONG, 1L);
    for (KeyTypeValue kv : valueOfEveryType) {
        rootDir.addSubdirectory(new KeySpaceDirectory(kv.keyType.toString(), kv.keyType, kv.value));
    }
    KeySpace root = new KeySpace(rootDir);
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    try (FDBRecordContext context = database.openContext()) {
        // Test all constants that match the ones we created with
        for (KeyTypeValue kv : valueOfEveryType) {
            assertEquals(Tuple.from(1L, kv.value), root.path("root").add(kv.keyType.toString()).toTuple(context));
            assertEquals(Tuple.from(1L, kv.value), root.path("root").add(kv.keyType.toString(), kv.value).toTuple(context));
            // Try a different value of the same type and make sure that fails
            if (kv.keyType != KeyType.NULL) {
                assertThrows(RecordCoreArgumentException.class, () -> root.path("root").add(kv.keyType.toString(), kv.value2).toTuple(context));
            }
            // Try a completely different type and make sure that fails
            final Object badValue = pickDifferentType(kv.keyType).generator.get();
            assertThrows(RecordCoreArgumentException.class, () -> root.path("root").add(kv.keyType.toString(), badValue).toTuple(context));
        }
    }
}
Also used : FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Test(org.junit.jupiter.api.Test)

Example 25 with FDBDatabase

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

the class KeySpaceDirectoryTest method testListDirectoryLayer.

@Test
public void testListDirectoryLayer() throws Exception {
    KeySpace root = new KeySpace(new KeySpaceDirectory("a", KeyType.LONG, random.nextLong()).addSubdirectory(new DirectoryLayerDirectory("b")).addSubdirectory(new KeySpaceDirectory("c", KeyType.STRING, "c").addSubdirectory(new DirectoryLayerDirectory("d", "d")).addSubdirectory(new DirectoryLayerDirectory("e", "e")).addSubdirectory(new DirectoryLayerDirectory("f", "f"))));
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    try (FDBRecordContext context = database.openContext()) {
        Transaction tr = context.ensureActive();
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 5; j++) {
                Tuple key = root.path("a").add("b", "value_" + i).toTuple(context).add(i).add(j);
                tr.set(key.pack(), Tuple.from(i).pack());
            }
        }
        for (int i = 0; i < 5; i++) {
            tr.set(root.path("a").add("c").add("d").toTuple(context).add(i).pack(), Tuple.from(i).pack());
            tr.set(root.path("a").add("c").add("e").toTuple(context).add(i).pack(), Tuple.from(i).pack());
            tr.set(root.path("a").add("c").add("f").toTuple(context).add(i).pack(), Tuple.from(i).pack());
        }
        context.commit();
    }
    try (FDBRecordContext context = database.openContext()) {
        List<ResolvedKeySpacePath> paths = root.path("a").listSubdirectory(context, "b");
        assertEquals(10, paths.size());
        for (ResolvedKeySpacePath path : paths) {
            // The first part of the remainder was the index
            final long index = path.getRemainder().getLong(0);
            // We should always get the "first" key for the value in the directory
            assertEquals(0, path.getRemainder().getLong(1));
            assertTrue(index >= 0 && index < 10);
            assertEquals("a", path.getParent().getDirectoryName());
            assertEquals(root.getDirectory("a").getValue(), path.getParent().getLogicalValue());
            assertEquals("value_" + index, path.getLogicalValue());
        }
        for (String subdir : ImmutableList.of("d", "e", "f")) {
            paths = root.path("a").add("c").listSubdirectory(context, subdir);
            assertEquals(1, paths.size());
            assertEquals(subdir, paths.get(0).getLogicalValue());
            assertEquals(0L, paths.get(0).getRemainder().getLong(0));
            assertEquals("c", paths.get(0).getParent().getDirectoryName());
            assertEquals("a", paths.get(0).getParent().getParent().getDirectoryName());
        }
    }
}
Also used : Transaction(com.apple.foundationdb.Transaction) 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)

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