Search in sources :

Example 1 with ValueRange

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

the class KeySpaceDirectory method listSubdirectoryAsync.

@Nonnull
// SonarQube doesn't realize that the cursor is wrapped and returned
@SuppressWarnings("squid:S2095")
protected RecordCursor<ResolvedKeySpacePath> listSubdirectoryAsync(@Nullable KeySpacePath listFrom, @Nonnull FDBRecordContext context, @Nonnull String subdirName, @Nullable ValueRange<?> valueRange, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties) {
    if (listFrom != null && listFrom.getDirectory() != this) {
        throw new RecordCoreException("Provided path does not belong to this directory").addLogInfo("path", listFrom, "directory", this.getName());
    }
    final KeySpaceDirectory subdir = getSubdirectory(subdirName);
    final CompletableFuture<ResolvedKeySpacePath> resolvedFromFuture = listFrom == null ? CompletableFuture.completedFuture(null) : listFrom.toResolvedPathAsync(context);
    // The chained cursor cannot implement reverse scan, so we implement it by having the
    // inner key value cursor do the reversing but telling the chained cursor we are moving
    // forward.
    final ScanProperties chainedCursorScanProperties;
    if (scanProperties.isReverse()) {
        chainedCursorScanProperties = scanProperties.setReverse(false);
    } else {
        chainedCursorScanProperties = scanProperties;
    }
    // For the read of the individual row keys, we only want to read a single key. In addition,
    // the ChainedCursor is going to do counting of our reads to apply any limits that were specified
    // on the ScanProperties.  We don't want the inner KeyValueCursor in nextTuple() to ALSO count those
    // same reads so we clear out its limits.
    final ScanProperties keyReadScanProperties = scanProperties.with(props -> props.clearState().setReturnedRowLimit(1));
    return new LazyCursor<>(resolvedFromFuture.thenCompose(resolvedFrom -> {
        final Subspace subspace = resolvedFrom == null ? new Subspace() : resolvedFrom.toSubspace();
        return subdir.getValueRange(context, valueRange, subspace).thenApply(range -> {
            final RecordCursor<Tuple> cursor = new ChainedCursor<>(context, lastKey -> nextTuple(context, subspace, range, lastKey, keyReadScanProperties), Tuple::pack, Tuple::fromBytes, continuation, chainedCursorScanProperties);
            return cursor.mapPipelined(tuple -> {
                final Tuple key = Tuple.fromList(tuple.getItems());
                return findChildForKey(context, resolvedFrom, key, 1, 0);
            }, 1);
        });
    }), context.getExecutor());
}
Also used : Arrays(java.util.Arrays) KeyRange(com.apple.foundationdb.record.KeyRange) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) LazyCursor(com.apple.foundationdb.record.cursors.LazyCursor) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) Subspace(com.apple.foundationdb.subspace.Subspace) ArrayList(java.util.ArrayList) Tuple(com.apple.foundationdb.tuple.Tuple) EndpointType(com.apple.foundationdb.record.EndpointType) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) ScanProperties(com.apple.foundationdb.record.ScanProperties) Map(java.util.Map) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) KeyValue(com.apple.foundationdb.KeyValue) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) ChainedCursor(com.apple.foundationdb.record.cursors.ChainedCursor) StringWriter(java.io.StringWriter) IOException(java.io.IOException) UUID(java.util.UUID) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Objects(java.util.Objects) KeyValueCursor(com.apple.foundationdb.record.provider.foundationdb.KeyValueCursor) List(java.util.List) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Writer(java.io.Writer) RecordCursor(com.apple.foundationdb.record.RecordCursor) ValueRange(com.apple.foundationdb.record.ValueRange) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) BitSet(java.util.BitSet) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) LazyCursor(com.apple.foundationdb.record.cursors.LazyCursor) RecordCursor(com.apple.foundationdb.record.RecordCursor) ScanProperties(com.apple.foundationdb.record.ScanProperties) Subspace(com.apple.foundationdb.subspace.Subspace) Tuple(com.apple.foundationdb.tuple.Tuple) Nonnull(javax.annotation.Nonnull)

Example 2 with ValueRange

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

the class KeySpaceDirectoryTest method testListAnyValue.

@Test
public void testListAnyValue() throws Exception {
    // Create a root directory called "a" with subdirs of every type (no constants for now)
    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));
    }
    KeySpace root = new KeySpace(dirA);
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    final Map<KeyType, List<Tuple>> valuesForType = new HashMap<>();
    // Create an entry in the keyspace with a row for every type that we support
    try (FDBRecordContext context = database.openContext()) {
        Transaction tr = context.ensureActive();
        for (KeyTypeValue kv : valueOfEveryType) {
            List<Tuple> values = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                Object value = kv.generator.get();
                Tuple tupleValue = Tuple.from(value);
                if (!values.contains(tupleValue)) {
                    values.add(tupleValue);
                    // final results.
                    for (int j = 0; j < 5; j++) {
                        tr.set(Tuple.from(rootValue, value, j).pack(), Tuple.from(i).pack());
                    }
                }
            }
            valuesForType.put(kv.keyType, values);
        }
        context.commit();
    }
    try (FDBRecordContext context = database.openContext()) {
        for (KeyTypeValue kv : valueOfEveryType) {
            if (kv.keyType != KeyType.NULL) {
                List<Tuple> values = valuesForType.get(kv.keyType);
                for (Pair<ValueRange<Object>, List<Tuple>> testCase : listRangeTestCases(values)) {
                    testListRange(testCase.getLeft(), testCase.getRight(), context, root, kv.keyType);
                }
            }
        }
    }
}
Also used : KeyType(com.apple.foundationdb.record.provider.foundationdb.keyspace.KeySpaceDirectory.KeyType) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) ValueRange(com.apple.foundationdb.record.ValueRange) Transaction(com.apple.foundationdb.Transaction) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 3 with ValueRange

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

the class KeySpaceDirectoryTest method testInvalidListRange.

@Test
public void testInvalidListRange() throws Exception {
    final String rootDir = "root_dir";
    final String stringDir = "string_dir";
    final String longConstDir = "long_const_dir";
    KeySpaceDirectory dirA = new KeySpaceDirectory(rootDir, KeyType.LONG, random.nextLong()).addSubdirectory(new KeySpaceDirectory(stringDir, KeyType.STRING)).addSubdirectory(new KeySpaceDirectory(longConstDir, KeyType.LONG, 100));
    KeySpace root = new KeySpace(dirA);
    final FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
    try (FDBRecordContext context = database.openContext()) {
        // Positive example.
        root.path(rootDir).listSubdirectory(context, stringDir, new ValueRange<>("A", "B", EndpointType.RANGE_INCLUSIVE, EndpointType.RANGE_EXCLUSIVE), null, ScanProperties.FORWARD_SCAN);
        // The range value should be in the same type.
        assertThrows(RecordCoreArgumentException.class, () -> root.path(rootDir).listSubdirectory(context, stringDir, new ValueRange<>(100, 200, EndpointType.RANGE_INCLUSIVE, EndpointType.RANGE_EXCLUSIVE), null, ScanProperties.FORWARD_SCAN));
        // PREFIX_STRING should not be used as a endpoint type.
        assertThrows(RecordCoreArgumentException.class, () -> root.path(rootDir).listSubdirectory(context, stringDir, new ValueRange<>("A", "B", EndpointType.PREFIX_STRING, EndpointType.RANGE_EXCLUSIVE), null, ScanProperties.FORWARD_SCAN));
        // Range should be null when the subdirectory has a value.
        assertThrows(RecordCoreArgumentException.class, () -> root.path(rootDir).listSubdirectory(context, longConstDir, new ValueRange<>(100, 200, EndpointType.RANGE_INCLUSIVE, EndpointType.RANGE_EXCLUSIVE), null, ScanProperties.FORWARD_SCAN));
    }
}
Also used : ValueRange(com.apple.foundationdb.record.ValueRange) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) FDBDatabase(com.apple.foundationdb.record.provider.foundationdb.FDBDatabase) Test(org.junit.jupiter.api.Test)

Aggregations

ValueRange (com.apple.foundationdb.record.ValueRange)3 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)3 FDBDatabase (com.apple.foundationdb.record.provider.foundationdb.FDBDatabase)2 Tuple (com.apple.foundationdb.tuple.Tuple)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Test (org.junit.jupiter.api.Test)2 KeyValue (com.apple.foundationdb.KeyValue)1 Transaction (com.apple.foundationdb.Transaction)1 API (com.apple.foundationdb.annotation.API)1 EndpointType (com.apple.foundationdb.record.EndpointType)1 KeyRange (com.apple.foundationdb.record.KeyRange)1 RecordCoreArgumentException (com.apple.foundationdb.record.RecordCoreArgumentException)1 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)1 RecordCursor (com.apple.foundationdb.record.RecordCursor)1 ScanProperties (com.apple.foundationdb.record.ScanProperties)1 ChainedCursor (com.apple.foundationdb.record.cursors.ChainedCursor)1 LazyCursor (com.apple.foundationdb.record.cursors.LazyCursor)1 LogMessageKeys (com.apple.foundationdb.record.logging.LogMessageKeys)1