Search in sources :

Example 46 with KeyValue

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

the class RankedSet method checkConsistency.

protected Consistency checkConsistency(ReadTransactionContext tc) {
    return tc.read(tr -> {
        final int nlevels = config.getNLevels();
        for (int level = 1; level < nlevels; ++level) {
            byte[] prevKey = null;
            long prevCount = 0;
            AsyncIterator<KeyValue> it = tr.getRange(subspace.range(Tuple.from(level))).iterator();
            while (true) {
                boolean more = it.hasNext();
                KeyValue kv = more ? it.next() : null;
                byte[] nextKey = kv == null ? null : subspace.unpack(kv.getKey()).getBytes(1);
                if (prevKey != null) {
                    long count = countRange(tr, level - 1, prevKey, nextKey).join();
                    if (prevCount != count) {
                        return new Consistency(level, prevCount, count, toDebugString(tc));
                    }
                }
                if (!more) {
                    break;
                }
                prevKey = nextKey;
                prevCount = decodeLong(kv.getValue());
            }
        }
        return new Consistency();
    });
}
Also used : KeyValue(com.apple.foundationdb.KeyValue)

Example 47 with KeyValue

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

the class PermutedMinMaxIndexMaintainer method scan.

@Nonnull
@Override
public RecordCursor<IndexEntry> scan(@Nonnull IndexScanType scanType, @Nonnull TupleRange range, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties) {
    if (scanType == IndexScanType.BY_VALUE) {
        return scan(range, continuation, scanProperties);
    }
    if (scanType == IndexScanType.BY_GROUP) {
        final Subspace permutedSubspace = getSecondarySubspace();
        final RecordCursor<KeyValue> keyValues = KeyValueCursor.Builder.withSubspace(permutedSubspace).setContext(state.context).setRange(range).setContinuation(continuation).setScanProperties(scanProperties).build();
        return keyValues.map(kv -> {
            state.store.countKeyValue(FDBStoreTimer.Counts.LOAD_INDEX_KEY, FDBStoreTimer.Counts.LOAD_INDEX_KEY_BYTES, FDBStoreTimer.Counts.LOAD_INDEX_VALUE_BYTES, kv);
            return unpackKeyValue(permutedSubspace, kv);
        });
    }
    throw new RecordCoreException("Can only scan permuted index by value or group.");
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) KeyValue(com.apple.foundationdb.KeyValue) Subspace(com.apple.foundationdb.subspace.Subspace) Nonnull(javax.annotation.Nonnull)

Example 48 with KeyValue

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

the class SplitHelper method loadWithSplit.

/**
 * Load serialized byte array that may be split among several keys.
 * @param tr read transaction
 * @param context transaction context
 * @param subspace subspace containing serialized value
 * @param key key within subspace
 * @param splitLongRecords <code>true</code> if multiple keys should be used; if <code>false</code>, <code>serialized</code> must fit in a single key
 * @param missingUnsplitRecordSuffix if <code>splitLongRecords</code> is <code>false</code> and this is <code>true</code>, this will assume keys are missing a suffix for backwards compatibility reasons
 * @param sizeInfo optional size information to populate
 * @return the merged byte array
 */
public static CompletableFuture<FDBRawRecord> loadWithSplit(@Nonnull final ReadTransaction tr, @Nonnull final FDBRecordContext context, @Nonnull final Subspace subspace, @Nonnull final Tuple key, final boolean splitLongRecords, final boolean missingUnsplitRecordSuffix, @Nullable SizeInfo sizeInfo) {
    if (!splitLongRecords && missingUnsplitRecordSuffix) {
        return loadUnsplitLegacy(tr, context, subspace, key, sizeInfo);
    }
    // Even if long records are not split, then unless we are using the old format, it might be the case
    // that there is a record version associated with this key, hence the range read.
    // It is still better to do a range read in that case than two point reads (probably).
    final long startTime = System.nanoTime();
    final Subspace recordSubspace = subspace.subspace(key);
    // Note that recordSubspace.range() includes only keys that are a strict prefix of recordSubspace.pack(). This means
    // it excludes recordSubspace.pack() itself as well as any keys that are greater than or equal to recordSubspace.pack() + \xff.
    final AsyncIterable<KeyValue> rangeScan = tr.getRange(recordSubspace.range(), ReadTransaction.ROW_LIMIT_UNLIMITED, false, StreamingMode.WANT_ALL);
    final AsyncIterator<KeyValue> rangeIter = rangeScan.iterator();
    context.instrument(FDBStoreTimer.DetailEvents.GET_RECORD_RANGE_RAW_FIRST_CHUNK, rangeIter.onHasNext(), startTime);
    return new SingleKeyUnsplitter(context, key, recordSubspace, rangeIter, sizeInfo).run(context.getExecutor());
}
Also used : KeyValue(com.apple.foundationdb.KeyValue) Subspace(com.apple.foundationdb.subspace.Subspace)

Example 49 with KeyValue

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

the class ResolverMappingReplicator method copyInternal.

private CompletableFuture<Void> copyInternal(@Nonnull final LocatableResolver replica, @Nonnull final LongAccumulator accumulator, @Nonnull final AtomicInteger counter) {
    ExecuteProperties executeProperties = ExecuteProperties.newBuilder().setReturnedRowLimit(transactionRowLimit).setTimeLimit(transactionTimeLimitMillis).setIsolationLevel(IsolationLevel.SNAPSHOT).build();
    final AtomicReference<byte[]> continuation = new AtomicReference<>(null);
    return AsyncUtil.whileTrue(() -> {
        final FDBRecordContext context = runner.openContext();
        return primary.getMappingSubspaceAsync().thenCompose(primaryMappingSubspace -> {
            RecordCursor<KeyValue> cursor = KeyValueCursor.Builder.withSubspace(primaryMappingSubspace).setScanProperties(new ScanProperties(executeProperties)).setContext(context).setContinuation(continuation.get()).build();
            return cursor.forEachResultAsync(result -> {
                KeyValue kv = result.get();
                final String mappedString = primaryMappingSubspace.unpack(kv.getKey()).getString(0);
                final ResolverResult mappedValue = valueDeserializer.apply(kv.getValue());
                accumulator.accumulate(mappedValue.getValue());
                counter.incrementAndGet();
                return replica.setMapping(context, mappedString, mappedValue);
            }).thenCompose(lastResult -> context.commitAsync().thenRun(() -> {
                byte[] nextContinuationBytes = lastResult.getContinuation().toBytes();
                if (LOGGER.isInfoEnabled()) {
                    LOGGER.info(KeyValueLogMessage.of("committing batch", LogMessageKeys.SCANNED_SO_FAR, counter.get(), LogMessageKeys.NEXT_CONTINUATION, ByteArrayUtil2.loggable(nextContinuationBytes)));
                }
                continuation.set(nextContinuationBytes);
            })).whenComplete((vignore, eignore) -> cursor.close()).thenApply(vignore -> Objects.nonNull(continuation.get()));
        });
    }, runner.getExecutor());
}
Also used : IsolationLevel(com.apple.foundationdb.record.IsolationLevel) Logger(org.slf4j.Logger) KeyValue(com.apple.foundationdb.KeyValue) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) FDBStoreTimer(com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer) LoggerFactory(org.slf4j.LoggerFactory) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Objects(java.util.Objects) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) KeyValueCursor(com.apple.foundationdb.record.provider.foundationdb.KeyValueCursor) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) LongAccumulator(java.util.concurrent.atomic.LongAccumulator) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ScanProperties(com.apple.foundationdb.record.ScanProperties) RecordCursor(com.apple.foundationdb.record.RecordCursor) API(com.apple.foundationdb.annotation.API) FDBDatabaseRunner(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseRunner) Nonnull(javax.annotation.Nonnull) ByteArrayUtil2(com.apple.foundationdb.tuple.ByteArrayUtil2) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) KeyValue(com.apple.foundationdb.KeyValue) FDBRecordContext(com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext) ScanProperties(com.apple.foundationdb.record.ScanProperties) AtomicReference(java.util.concurrent.atomic.AtomicReference)

Example 50 with KeyValue

use of com.apple.foundationdb.KeyValue in project lionrock by panghy.

the class GrpcAsyncIterableTest method iterator.

@Test
void iterator() {
    // setup mocks.
    GrpcAsyncIterator.RemovalCallback<KeyValue> removalCallback = mock(GrpcAsyncIterator.RemovalCallback.class);
    GrpcAsyncIterable.FetchIssuer<GetRangeResponse> fetchIssuer = mock(GrpcAsyncIterable.FetchIssuer.class);
    GrpcAsyncIterable<KeyValue, GetRangeResponse> iterable = new GrpcAsyncIterable<>(removalCallback, resp -> resp.getKeyValuesList().stream().map(x -> new com.apple.foundationdb.KeyValue(x.getKey().toByteArray(), x.getValue().toByteArray())), GetRangeResponse::getDone, NamedCompletableFuture::new, fetchIssuer, MoreExecutors.directExecutor());
    AsyncIterator<KeyValue> iterator = iterable.iterator();
    verify(fetchIssuer, times(1)).issue(respCaptor.capture(), failureCaptor.capture());
    Consumer<GetRangeResponse> value = respCaptor.getValue();
    CompletableFuture<Boolean> cf = iterator.onHasNext();
    assertFalse(cf.isDone());
    value.accept(GetRangeResponse.newBuilder().addKeyValues(io.github.panghy.lionrock.proto.KeyValue.newBuilder().setKey(ByteString.copyFrom("hello", StandardCharsets.UTF_8)).setValue(ByteString.copyFrom("world", StandardCharsets.UTF_8)).build()).build());
    assertTrue(cf.isDone());
    assertTrue(iterator.hasNext());
    KeyValue next = iterator.next();
    assertArrayEquals("hello".getBytes(StandardCharsets.UTF_8), next.getKey());
    cf = iterator.onHasNext();
    assertFalse(cf.isDone());
    value.accept(GetRangeResponse.newBuilder().setDone(true).addKeyValues(io.github.panghy.lionrock.proto.KeyValue.newBuilder().setKey(ByteString.copyFrom("hello2", StandardCharsets.UTF_8)).setValue(ByteString.copyFrom("world2", StandardCharsets.UTF_8)).build()).build());
    assertTrue(cf.isDone());
    assertTrue(iterator.hasNext());
    next = iterator.next();
    assertArrayEquals("hello2".getBytes(StandardCharsets.UTF_8), next.getKey());
    iterator.remove();
    iterator.onHasNext();
    assertTrue(cf.isDone());
    assertFalse(iterator.hasNext());
    verify(removalCallback, times(1)).deleteKey(eq(new KeyValue("hello2".getBytes(StandardCharsets.UTF_8), "world2".getBytes(StandardCharsets.UTF_8))));
    // get another iterator.
    iterator = iterable.iterator();
    verify(fetchIssuer, times(2)).issue(respCaptor.capture(), failureCaptor.capture());
    value = respCaptor.getValue();
    cf = iterator.onHasNext();
    assertFalse(cf.isDone());
    value.accept(GetRangeResponse.newBuilder().setDone(true).addKeyValues(io.github.panghy.lionrock.proto.KeyValue.newBuilder().setKey(ByteString.copyFrom("hello2", StandardCharsets.UTF_8)).setValue(ByteString.copyFrom("world2", StandardCharsets.UTF_8)).build()).build());
    assertTrue(cf.isDone());
    assertTrue(iterator.hasNext());
    next = iterator.next();
    assertArrayEquals("hello2".getBytes(StandardCharsets.UTF_8), next.getKey());
    iterator.onHasNext();
    assertTrue(cf.isDone());
    assertFalse(iterator.hasNext());
}
Also used : MoreExecutors(com.google.common.util.concurrent.MoreExecutors) MockitoExtension(org.mockito.junit.jupiter.MockitoExtension) KeyValue(com.apple.foundationdb.KeyValue) AsyncIterator(com.apple.foundationdb.async.AsyncIterator) CompletableFuture(java.util.concurrent.CompletableFuture) Captor(org.mockito.Captor) StandardCharsets(java.nio.charset.StandardCharsets) OperationFailureResponse(io.github.panghy.lionrock.proto.OperationFailureResponse) ByteString(com.google.protobuf.ByteString) Test(org.junit.jupiter.api.Test) Consumer(java.util.function.Consumer) Mockito(org.mockito.Mockito) List(java.util.List) ArgumentCaptor(org.mockito.ArgumentCaptor) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Assertions(org.junit.jupiter.api.Assertions) NamedCompletableFuture(io.github.panghy.lionrock.client.foundationdb.impl.NamedCompletableFuture) GetRangeResponse(io.github.panghy.lionrock.proto.GetRangeResponse) KeyValue(com.apple.foundationdb.KeyValue) GetRangeResponse(io.github.panghy.lionrock.proto.GetRangeResponse) NamedCompletableFuture(io.github.panghy.lionrock.client.foundationdb.impl.NamedCompletableFuture) Test(org.junit.jupiter.api.Test)

Aggregations

KeyValue (com.apple.foundationdb.KeyValue)51 Test (org.junit.jupiter.api.Test)23 Subspace (com.apple.foundationdb.subspace.Subspace)22 Nonnull (javax.annotation.Nonnull)22 CompletableFuture (java.util.concurrent.CompletableFuture)19 List (java.util.List)18 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)16 ArrayList (java.util.ArrayList)16 Transaction (com.apple.foundationdb.Transaction)15 ScanProperties (com.apple.foundationdb.record.ScanProperties)15 Tuple (com.apple.foundationdb.tuple.Tuple)14 Map (java.util.Map)14 Collectors (java.util.stream.Collectors)12 Nullable (javax.annotation.Nullable)12 ByteArrayUtil (com.apple.foundationdb.tuple.ByteArrayUtil)11 AtomicReference (java.util.concurrent.atomic.AtomicReference)11 AsyncIterator (com.apple.foundationdb.async.AsyncIterator)10 ExecuteProperties (com.apple.foundationdb.record.ExecuteProperties)10 Collections (java.util.Collections)10 ReadTransaction (com.apple.foundationdb.ReadTransaction)9