Search in sources :

Example 1 with ReadTransaction

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

the class RangeSet method insertRange.

/**
 * Inserts a range into the set. The range inserted will begin at <code>begin</code> (inclusive) and end at
 * <code>end</code> (exclusive). If the <code>requireEmpty</code> is set, then this will only actually change the
 * database in the case that the range being added is not yet included in the set. If this flag is set to
 * <code>false</code>, then this will "fill in the gaps" between ranges present so that the whole range is
 * present following this transactions operation. The return value will (when ready) be equal to <code>true</code>
 * if and only if there are changes (i.e., writes) to the database that need to be made, i.e., the range was not
 * already included in the set. If the initial end point is less than the begin point, then this will
 * throw an {@link IllegalArgumentException} indicating that one has passed an inverted range. If <code>begin</code>
 * and <code>end</code> are equal, then this will immediately return a future that is set to <code>false</code>
 * (corresponding to adding an empty range). If <code>null</code> is set for either endpoint, this will insert
 * a range all the way to the end of the total range.
 *
 * <p>
 * In terms of isolation, this method will add both read- and write-conflict ranges. It adds a read-conflict range
 * corresponding to the range being added, i.e., for the keys within the range from <code>begin</code> to <code>end</code>.
 * This is so that if this range is modified concurrently by another writer, this transaction will fail (as the exact
 * writes done depend on these keys not being modified.) It will also a write-conflict ranges corresponding
 * to all of the individual ranges added to the database. That means that if the range is initially empty,
 * a write-conflict range corresponding to the keys from <code>begin</code> to <code>end</code>. This is done
 * so that if another transaction checks to see if a key in the range we are writing is within the range set
 * and finds that it is not, this write will then cause that transaction to fail if it is committed after this
 * one. If the range is not empty initially, write conflict ranges are added for all of the "gaps" that have
 * to be added. (So, if the range is already full, then no write conflict ranges are added at all.)
 * </p>
 *
 * @param tc the transaction or database in which to operate
 * @param begin the (inclusive) beginning of the range to add
 * @param end the (exclusive) end of the range to add
 * @param requireEmpty whether this should only be added if this range is initially empty
 * @return a future that is <code>true</code> if there were any modifications to the database and <code>false</code> otherwise
 */
@Nonnull
public CompletableFuture<Boolean> insertRange(@Nonnull TransactionContext tc, @Nullable byte[] begin, @Nullable byte[] end, boolean requireEmpty) {
    byte[] beginNonNull = (begin == null) ? FIRST_KEY : begin;
    byte[] endNonNull = (end == null) ? FINAL_KEY : end;
    checkKey(beginNonNull);
    checkRange(beginNonNull, endNonNull);
    if (ByteArrayUtil.compareUnsigned(beginNonNull, endNonNull) == 0) {
        return AsyncUtil.READY_FALSE;
    }
    return tc.runAsync(tr -> {
        // Add a read range for the keys corresponding to the bounds of this range.
        byte[] frobnicatedBegin = subspace.pack(beginNonNull);
        byte[] frobnicatedEnd = subspace.pack(endNonNull);
        tr.addReadConflictRange(frobnicatedBegin, frobnicatedEnd);
        // Look to see what is already in this database to see what of this range is already present.
        // Note: the two range reads are done in parallel, which essentially means we get the before read
        // "for free".
        byte[] keyAfterBegin = keyAfter(frobnicatedBegin);
        ReadTransaction snapshot = tr.snapshot();
        AsyncIterator<KeyValue> beforeIterator = snapshot.getRange(subspace.range().begin, keyAfterBegin, 1, true).iterator();
        AsyncIterator<KeyValue> afterIterator = snapshot.getRange(keyAfterBegin, frobnicatedEnd, (requireEmpty ? 1 : ReadTransaction.ROW_LIMIT_UNLIMITED), false).iterator();
        return beforeIterator.onHasNext().thenCompose(hasBefore -> {
            AtomicReference<byte[]> lastSeen = new AtomicReference<>(frobnicatedBegin);
            KeyValue before = hasBefore ? beforeIterator.next() : null;
            // end of that range.
            if (hasBefore) {
                byte[] beforeEnd = before.getValue();
                if (ByteArrayUtil.compareUnsigned(beginNonNull, beforeEnd) < 0) {
                    if (requireEmpty) {
                        return AsyncUtil.READY_FALSE;
                    } else {
                        lastSeen.set(subspace.pack(beforeEnd));
                    }
                }
            }
            if (requireEmpty) {
                // If we will only add on the empty case, then the after iterator has to be empty.
                return afterIterator.onHasNext().thenApply(hasNext -> {
                    if (hasNext) {
                        return false;
                    } else {
                        if (before != null && ByteArrayUtil.compareUnsigned(beginNonNull, before.getValue()) == 0) {
                            // This consolidation is done to make the simple case of a single writer
                            // going forward more space compact.
                            tr.addReadConflictKey(before.getKey());
                            tr.set(before.getKey(), endNonNull);
                        } else {
                            tr.set(frobnicatedBegin, endNonNull);
                        }
                        tr.addWriteConflictRange(frobnicatedBegin, frobnicatedEnd);
                        return true;
                    }
                });
            } else {
                AtomicBoolean changed = new AtomicBoolean(false);
                // If we are allowing non-empty ranges, then we just need to fill in the gaps.
                return AsyncUtil.whileTrue(() -> {
                    byte[] lastSeenBytes = lastSeen.get();
                    if (MoreAsyncUtil.isCompletedNormally(afterIterator.onHasNext()) && afterIterator.hasNext()) {
                        KeyValue kv = afterIterator.next();
                        if (ByteArrayUtil.compareUnsigned(lastSeenBytes, kv.getKey()) < 0) {
                            tr.set(lastSeenBytes, subspace.unpack(kv.getKey()).getBytes(0));
                            tr.addWriteConflictRange(lastSeenBytes, kv.getKey());
                            changed.set(true);
                        }
                        lastSeen.set(subspace.pack(kv.getValue()));
                    }
                    return afterIterator.onHasNext();
                }, tc.getExecutor()).thenApply(vignore -> {
                    byte[] lastSeenBytes = lastSeen.get();
                    // Get from lastSeen to the end (the last gap).
                    if (ByteArrayUtil.compareUnsigned(lastSeenBytes, frobnicatedEnd) < 0) {
                        tr.set(lastSeenBytes, endNonNull);
                        tr.addWriteConflictRange(lastSeenBytes, frobnicatedEnd);
                        changed.set(true);
                    }
                    return changed.get();
                });
            }
        });
    });
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) KeyValue(com.apple.foundationdb.KeyValue) ReadTransaction(com.apple.foundationdb.ReadTransaction) AtomicReference(java.util.concurrent.atomic.AtomicReference) Nonnull(javax.annotation.Nonnull)

Example 2 with ReadTransaction

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

the class FDBRecordStore method getSnapshotRecordCount.

@Override
public CompletableFuture<Long> getSnapshotRecordCount(@Nonnull KeyExpression key, @Nonnull Key.Evaluated value, @Nonnull IndexQueryabilityFilter indexQueryabilityFilter) {
    if (getRecordMetaData().getRecordCountKey() != null) {
        if (key.getColumnSize() != value.size()) {
            throw recordCoreException("key and value are not the same size");
        }
        final ReadTransaction tr = context.readTransaction(true);
        final Tuple subkey = Tuple.from(RECORD_COUNT_KEY).addAll(value.toTupleAppropriateList());
        if (getRecordMetaData().getRecordCountKey().equals(key)) {
            return tr.get(getSubspace().pack(subkey)).thenApply(FDBRecordStore::decodeRecordCount);
        } else if (key.isPrefixKey(getRecordMetaData().getRecordCountKey())) {
            AsyncIterable<KeyValue> kvs = tr.getRange(getSubspace().range(Tuple.from(RECORD_COUNT_KEY)));
            return MoreAsyncUtil.reduce(getExecutor(), kvs.iterator(), 0L, (count, kv) -> count + decodeRecordCount(kv.getValue()));
        }
    }
    return evaluateAggregateFunction(Collections.emptyList(), IndexFunctionHelper.count(key), TupleRange.allOf(value.toTuple()), IsolationLevel.SNAPSHOT, indexQueryabilityFilter).thenApply(tuple -> tuple.getLong(0));
}
Also used : LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) UnaryOperator(java.util.function.UnaryOperator) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) RecordSerializer(com.apple.foundationdb.record.provider.common.RecordSerializer) Subspace(com.apple.foundationdb.subspace.Subspace) MutationType(com.apple.foundationdb.MutationType) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Map(java.util.Map) RecordIndexUniquenessViolation(com.apple.foundationdb.record.RecordIndexUniquenessViolation) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Set(java.util.Set) TupleRange(com.apple.foundationdb.record.TupleRange) KeySpacePath(com.apple.foundationdb.record.provider.foundationdb.keyspace.KeySpacePath) ByteOrder(java.nio.ByteOrder) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) RecordMetaDataProvider(com.apple.foundationdb.record.RecordMetaDataProvider) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) API(com.apple.foundationdb.annotation.API) FunctionNames(com.apple.foundationdb.record.FunctionNames) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RangeSet(com.apple.foundationdb.async.RangeSet) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Supplier(java.util.function.Supplier) FormerIndex(com.apple.foundationdb.record.metadata.FormerIndex) ArrayList(java.util.ArrayList) ByteScanLimiter(com.apple.foundationdb.record.ByteScanLimiter) ParameterRelationshipGraph(com.apple.foundationdb.record.query.ParameterRelationshipGraph) LoggableException(com.apple.foundationdb.util.LoggableException) CloseableAsyncIterator(com.apple.foundationdb.async.CloseableAsyncIterator) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) Nullable(javax.annotation.Nullable) ByteArrayUtil2(com.apple.foundationdb.tuple.ByteArrayUtil2) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) CursorLimitManager(com.apple.foundationdb.record.cursors.CursorLimitManager) ExecuteState(com.apple.foundationdb.record.ExecuteState) AtomicLong(java.util.concurrent.atomic.AtomicLong) RecordType(com.apple.foundationdb.record.metadata.RecordType) Index(com.apple.foundationdb.record.metadata.Index) DynamicMessageRecordSerializer(com.apple.foundationdb.record.provider.common.DynamicMessageRecordSerializer) SyntheticRecordPlanner(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordPlanner) IndexEntry(com.apple.foundationdb.record.IndexEntry) LoggerFactory(org.slf4j.LoggerFactory) RecordCoreStorageException(com.apple.foundationdb.record.RecordCoreStorageException) ByteBuffer(java.nio.ByteBuffer) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) PipelineOperation(com.apple.foundationdb.record.PipelineOperation) RecordMetaDataProto(com.apple.foundationdb.record.RecordMetaDataProto) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) KeyValue(com.apple.foundationdb.KeyValue) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IndexQueryabilityFilter(com.apple.foundationdb.record.query.IndexQueryabilityFilter) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) List(java.util.List) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) AggregateFunctionNotSupportedException(com.apple.foundationdb.record.AggregateFunctionNotSupportedException) RecordTypeKeyComparison(com.apple.foundationdb.record.query.expressions.RecordTypeKeyComparison) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Optional(java.util.Optional) MutableRecordStoreState(com.apple.foundationdb.record.MutableRecordStoreState) RecordTypeOrBuilder(com.apple.foundationdb.record.metadata.RecordTypeOrBuilder) SyntheticRecordFromStoredRecordPlan(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordFromStoredRecordPlan) SpotBugsSuppressWarnings(com.apple.foundationdb.annotation.SpotBugsSuppressWarnings) Descriptors(com.google.protobuf.Descriptors) AsyncIterator(com.apple.foundationdb.async.AsyncIterator) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) CursorStreamingMode(com.apple.foundationdb.record.CursorStreamingMode) Key(com.apple.foundationdb.record.metadata.Key) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) EndpointType(com.apple.foundationdb.record.EndpointType) ScanProperties(com.apple.foundationdb.record.ScanProperties) Suppliers(com.google.common.base.Suppliers) LinkedList(java.util.LinkedList) Nonnull(javax.annotation.Nonnull) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) MoreAsyncUtil(com.apple.foundationdb.async.MoreAsyncUtil) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) IndexState(com.apple.foundationdb.record.IndexState) StoreRecordFunction(com.apple.foundationdb.record.metadata.StoreRecordFunction) ReadTransaction(com.apple.foundationdb.ReadTransaction) AsyncIterable(com.apple.foundationdb.async.AsyncIterable) FDBRecordStoreStateCache(com.apple.foundationdb.record.provider.foundationdb.storestate.FDBRecordStoreStateCache) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) ReadTransaction(com.apple.foundationdb.ReadTransaction) AsyncIterable(com.apple.foundationdb.async.AsyncIterable) Tuple(com.apple.foundationdb.tuple.Tuple)

Example 3 with ReadTransaction

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

the class FDBRecordStore method loadRecordVersionAsync.

/**
 * Async version of {@link #loadRecordVersion(Tuple, boolean)}.
 * @param primaryKey the primary key of the record
 * @param snapshot whether to snapshot read
 * @return a future that completes with the version of the record of {@code Optional.empty()} if versions are not enabled for this store
 */
@Nonnull
public Optional<CompletableFuture<FDBRecordVersion>> loadRecordVersionAsync(@Nonnull final Tuple primaryKey, final boolean snapshot) {
    final RecordMetaData metaData = metaDataProvider.getRecordMetaData();
    if (useOldVersionFormat() && !metaData.isStoreRecordVersions()) {
        // a priori that this will return an empty optional, so we return it without doing any I/O.
        return Optional.empty();
    } else {
        byte[] versionKey = getSubspace().pack(recordVersionKey(primaryKey));
        Optional<CompletableFuture<FDBRecordVersion>> cachedOptional = context.getLocalVersion(versionKey).map(localVersion -> CompletableFuture.completedFuture(FDBRecordVersion.incomplete(localVersion)));
        if (cachedOptional.isPresent()) {
            return cachedOptional;
        }
        final ReadTransaction tr = snapshot ? ensureContextActive().snapshot() : ensureContextActive();
        return Optional.of(tr.get(versionKey).thenApply(valueBytes -> {
            if (valueBytes == null) {
                return null;
            } else if (useOldVersionFormat()) {
                return FDBRecordVersion.complete(valueBytes, false);
            } else {
                return SplitHelper.unpackVersion(valueBytes);
            }
        }));
    }
}
Also used : LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) UnaryOperator(java.util.function.UnaryOperator) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) RecordSerializer(com.apple.foundationdb.record.provider.common.RecordSerializer) Subspace(com.apple.foundationdb.subspace.Subspace) MutationType(com.apple.foundationdb.MutationType) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Map(java.util.Map) RecordIndexUniquenessViolation(com.apple.foundationdb.record.RecordIndexUniquenessViolation) QueryToKeyMatcher(com.apple.foundationdb.record.query.QueryToKeyMatcher) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Set(java.util.Set) TupleRange(com.apple.foundationdb.record.TupleRange) KeySpacePath(com.apple.foundationdb.record.provider.foundationdb.keyspace.KeySpacePath) ByteOrder(java.nio.ByteOrder) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) RecordMetaDataProvider(com.apple.foundationdb.record.RecordMetaDataProvider) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) API(com.apple.foundationdb.annotation.API) FunctionNames(com.apple.foundationdb.record.FunctionNames) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) RangeSet(com.apple.foundationdb.async.RangeSet) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Supplier(java.util.function.Supplier) FormerIndex(com.apple.foundationdb.record.metadata.FormerIndex) ArrayList(java.util.ArrayList) ByteScanLimiter(com.apple.foundationdb.record.ByteScanLimiter) ParameterRelationshipGraph(com.apple.foundationdb.record.query.ParameterRelationshipGraph) LoggableException(com.apple.foundationdb.util.LoggableException) CloseableAsyncIterator(com.apple.foundationdb.async.CloseableAsyncIterator) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) Nullable(javax.annotation.Nullable) ByteArrayUtil2(com.apple.foundationdb.tuple.ByteArrayUtil2) IsolationLevel(com.apple.foundationdb.record.IsolationLevel) CursorLimitManager(com.apple.foundationdb.record.cursors.CursorLimitManager) ExecuteState(com.apple.foundationdb.record.ExecuteState) AtomicLong(java.util.concurrent.atomic.AtomicLong) RecordType(com.apple.foundationdb.record.metadata.RecordType) Index(com.apple.foundationdb.record.metadata.Index) DynamicMessageRecordSerializer(com.apple.foundationdb.record.provider.common.DynamicMessageRecordSerializer) SyntheticRecordPlanner(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordPlanner) IndexEntry(com.apple.foundationdb.record.IndexEntry) LoggerFactory(org.slf4j.LoggerFactory) RecordCoreStorageException(com.apple.foundationdb.record.RecordCoreStorageException) ByteBuffer(java.nio.ByteBuffer) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) PipelineOperation(com.apple.foundationdb.record.PipelineOperation) RecordMetaDataProto(com.apple.foundationdb.record.RecordMetaDataProto) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) KeyValue(com.apple.foundationdb.KeyValue) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IndexQueryabilityFilter(com.apple.foundationdb.record.query.IndexQueryabilityFilter) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) List(java.util.List) EvaluationContext(com.apple.foundationdb.record.EvaluationContext) AggregateFunctionNotSupportedException(com.apple.foundationdb.record.AggregateFunctionNotSupportedException) RecordTypeKeyComparison(com.apple.foundationdb.record.query.expressions.RecordTypeKeyComparison) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) Optional(java.util.Optional) MutableRecordStoreState(com.apple.foundationdb.record.MutableRecordStoreState) RecordTypeOrBuilder(com.apple.foundationdb.record.metadata.RecordTypeOrBuilder) SyntheticRecordFromStoredRecordPlan(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordFromStoredRecordPlan) SpotBugsSuppressWarnings(com.apple.foundationdb.annotation.SpotBugsSuppressWarnings) Descriptors(com.google.protobuf.Descriptors) AsyncIterator(com.apple.foundationdb.async.AsyncIterator) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) CursorStreamingMode(com.apple.foundationdb.record.CursorStreamingMode) Key(com.apple.foundationdb.record.metadata.Key) ExecuteProperties(com.apple.foundationdb.record.ExecuteProperties) EndpointType(com.apple.foundationdb.record.EndpointType) ScanProperties(com.apple.foundationdb.record.ScanProperties) Suppliers(com.google.common.base.Suppliers) LinkedList(java.util.LinkedList) Nonnull(javax.annotation.Nonnull) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) MoreAsyncUtil(com.apple.foundationdb.async.MoreAsyncUtil) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) IndexState(com.apple.foundationdb.record.IndexState) StoreRecordFunction(com.apple.foundationdb.record.metadata.StoreRecordFunction) ReadTransaction(com.apple.foundationdb.ReadTransaction) AsyncIterable(com.apple.foundationdb.async.AsyncIterable) FDBRecordStoreStateCache(com.apple.foundationdb.record.provider.foundationdb.storestate.FDBRecordStoreStateCache) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) CompletableFuture(java.util.concurrent.CompletableFuture) ReadTransaction(com.apple.foundationdb.ReadTransaction) Nonnull(javax.annotation.Nonnull)

Example 4 with ReadTransaction

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

the class FDBStoreTimerTest method testLowLevelIoMetrics.

@Test
public void testLowLevelIoMetrics() {
    final FDBStoreTimer timer = new FDBStoreTimer();
    try (FDBRecordContext context = fdb.openContext(null, timer)) {
        Transaction tr = context.ensureActive();
        tr.clear(subspace.range());
        tr.commit().join();
    }
    assertThat(timer.getCount(FDBStoreTimer.Counts.DELETES), equalTo(1));
    assertThat(timer.getCount(FDBStoreTimer.Events.COMMITS), equalTo(1));
    timer.reset();
    int writeBytes = 0;
    try (FDBRecordContext context = fdb.openContext(null, timer)) {
        Transaction tr = context.ensureActive();
        for (int i = 0; i < 5; i++) {
            byte[] key = subspace.pack(Tuple.from(i));
            byte[] value = subspace.pack(Tuple.from("foo", i));
            tr.set(key, value);
            writeBytes += (key.length + value.length);
        }
        ReadTransaction rtr = tr.snapshot();
        List<KeyValue> values = rtr.getRange(subspace.range()).asList().join();
        assertThat(values.size(), equalTo(5));
        tr.commit().join();
    }
    assertThat(timer.getCount(FDBStoreTimer.Counts.WRITES), equalTo(5));
    assertThat(timer.getCount(FDBStoreTimer.Counts.BYTES_WRITTEN), equalTo(writeBytes));
    assertThat(timer.getCount(FDBStoreTimer.Counts.READS), equalTo(1));
    assertThat(timer.getCount(FDBStoreTimer.Counts.BYTES_READ), equalTo(writeBytes));
    assertThat(timer.getCount(FDBStoreTimer.Events.COMMITS), equalTo(1));
}
Also used : KeyValue(com.apple.foundationdb.KeyValue) Transaction(com.apple.foundationdb.Transaction) ReadTransaction(com.apple.foundationdb.ReadTransaction) ReadTransaction(com.apple.foundationdb.ReadTransaction) Test(org.junit.jupiter.api.Test)

Example 5 with ReadTransaction

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

the class SplitHelperTest method loadWithSplit.

@Nullable
private FDBRawRecord loadWithSplit(@Nonnull FDBRecordContext context, @Nonnull Tuple key, boolean splitLongRecords, boolean omitUnsplitSuffix, @Nullable FDBStoredSizes expectedSizes, @Nullable byte[] expectedContents, @Nullable FDBRecordVersion expectedVersion) {
    final ReadTransaction tr = context.ensureActive();
    SplitHelper.SizeInfo sizeInfo = new SplitHelper.SizeInfo();
    FDBRawRecord rawRecord;
    try {
        rawRecord = SplitHelper.loadWithSplit(tr, context, subspace, key, splitLongRecords, omitUnsplitSuffix, sizeInfo).get();
    } catch (InterruptedException | ExecutionException e) {
        throw FDBExceptions.wrapException(e);
    }
    if (expectedSizes == null || expectedContents == null) {
        assertNull(rawRecord);
    } else {
        assertNotNull(rawRecord);
        assertArrayEquals(expectedContents, rawRecord.getRawRecord());
        int valueSize = expectedContents.length;
        if (expectedVersion != null) {
            valueSize += 1 + FDBRecordVersion.VERSION_LENGTH;
        }
        assertEquals(valueSize, rawRecord.getValueSize());
        if (!splitLongRecords) {
            assertThat(rawRecord.isSplit(), is(false));
        }
        if (omitUnsplitSuffix) {
            assertThat(rawRecord.isVersionedInline(), is(false));
        }
        boolean isSplit = rawRecord.getKeyCount() - (expectedVersion != null ? 1 : 0) != 1;
        assertEquals(isSplit, rawRecord.isSplit());
        assertEquals(key, rawRecord.getPrimaryKey());
        if (expectedVersion != null) {
            assertThat(rawRecord.isVersionedInline(), is(true));
            assertEquals(expectedVersion, rawRecord.getVersion());
        } else {
            assertThat(rawRecord.isVersionedInline(), is(false));
            assertNull(rawRecord.getVersion());
        }
        // Verify that the expected sizes are the same as the ones retrieved
        assertEquals(expectedSizes.getKeyCount(), rawRecord.getKeyCount());
        assertEquals(expectedSizes.getKeySize(), rawRecord.getKeySize());
        assertEquals(expectedSizes.getValueSize(), rawRecord.getValueSize());
        assertEquals(expectedSizes.isSplit(), rawRecord.isSplit());
        assertEquals(expectedSizes.isVersionedInline(), rawRecord.isVersionedInline());
        // Verify using sizeInfo and using the raw record get the same size information
        assertEquals(rawRecord.getKeyCount(), sizeInfo.getKeyCount());
        assertEquals(rawRecord.getKeySize(), sizeInfo.getKeySize());
        assertEquals(rawRecord.getValueSize(), sizeInfo.getValueSize());
        assertEquals(rawRecord.isSplit(), sizeInfo.isSplit());
        assertEquals(rawRecord.isVersionedInline(), sizeInfo.isVersionedInline());
    }
    return rawRecord;
}
Also used : ReadTransaction(com.apple.foundationdb.ReadTransaction) ExecutionException(java.util.concurrent.ExecutionException) Nullable(javax.annotation.Nullable)

Aggregations

ReadTransaction (com.apple.foundationdb.ReadTransaction)7 Nonnull (javax.annotation.Nonnull)5 KeyValue (com.apple.foundationdb.KeyValue)4 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)4 Transaction (com.apple.foundationdb.Transaction)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 MutationType (com.apple.foundationdb.MutationType)2 Range (com.apple.foundationdb.Range)2 API (com.apple.foundationdb.annotation.API)2 SpotBugsSuppressWarnings (com.apple.foundationdb.annotation.SpotBugsSuppressWarnings)2 AsyncIterable (com.apple.foundationdb.async.AsyncIterable)2 AsyncIterator (com.apple.foundationdb.async.AsyncIterator)2 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)2 CloseableAsyncIterator (com.apple.foundationdb.async.CloseableAsyncIterator)2 MoreAsyncUtil (com.apple.foundationdb.async.MoreAsyncUtil)2 RangeSet (com.apple.foundationdb.async.RangeSet)2 AggregateFunctionNotSupportedException (com.apple.foundationdb.record.AggregateFunctionNotSupportedException)2 ByteScanLimiter (com.apple.foundationdb.record.ByteScanLimiter)2 CursorStreamingMode (com.apple.foundationdb.record.CursorStreamingMode)2 EndpointType (com.apple.foundationdb.record.EndpointType)2