use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext in project fdb-record-layer by FoundationDB.
the class ResolverMappingDigest method computeDigest.
public CompletableFuture<byte[]> computeDigest() {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance(ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("invalid directory layer digest algorithm", e);
}
FDBRecordContext context = runner.openContext();
return computeInternal(context, null, messageDigest).thenCompose(continuation -> {
context.close();
if (continuation != null) {
return computeInternal(runner.openContext(), continuation, messageDigest);
}
return CompletableFuture.completedFuture(null);
}).thenApply(ignore -> messageDigest.digest());
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext in project fdb-record-layer by FoundationDB.
the class MetaDataVersionStampStoreStateCache method get.
@Nonnull
@Override
public CompletableFuture<FDBRecordStoreStateCacheEntry> get(@Nonnull FDBRecordStore recordStore, @Nonnull FDBRecordStoreBase.StoreExistenceCheck existenceCheck) {
final FDBRecordContext context = recordStore.getContext();
validateContext(context);
if (context.hasDirtyStoreState()) {
recordStore.increment(FDBStoreTimer.Counts.STORE_STATE_CACHE_MISS);
return FDBRecordStoreStateCacheEntry.load(recordStore, existenceCheck);
}
final SubspaceProvider subspaceProvider = recordStore.getSubspaceProvider();
final FDBRecordStoreStateCacheEntry existingEntry = cache.getIfPresent(subspaceProvider);
if (existingEntry == null) {
recordStore.increment(FDBStoreTimer.Counts.STORE_STATE_CACHE_MISS);
return FDBRecordStoreStateCacheEntry.load(recordStore, existenceCheck).whenComplete((cacheEntry, err) -> {
if (err == null && cacheEntry.getRecordStoreState().getStoreHeader().getCacheable()) {
addToCache(subspaceProvider, cacheEntry);
}
});
} else {
return recordStore.getContext().getMetaDataVersionStampAsync(IsolationLevel.SNAPSHOT).thenCompose(metaDataVersionStamp -> {
if (metaDataVersionStamp == null || existingEntry.getMetaDataVersionStamp() == null || ByteArrayUtil.compareUnsigned(metaDataVersionStamp, existingEntry.getMetaDataVersionStamp()) != 0) {
recordStore.increment(FDBStoreTimer.Counts.STORE_STATE_CACHE_MISS);
return FDBRecordStoreStateCacheEntry.load(recordStore, existenceCheck).whenComplete((cacheEntry, err) -> {
if (err == null && metaDataVersionStamp != null) {
if (cacheEntry.getRecordStoreState().getStoreHeader().getCacheable()) {
addToCache(subspaceProvider, cacheEntry);
} else {
invalidateOlderEntry(subspaceProvider, metaDataVersionStamp);
}
}
});
} else {
recordStore.increment(FDBStoreTimer.Counts.STORE_STATE_CACHE_HIT);
return existingEntry.handleCachedState(context, existenceCheck).thenApply(ignore -> existingEntry);
}
});
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext in project fdb-record-layer by FoundationDB.
the class ChainedCursorTest method limitBy.
private void limitBy(int returnedRowLimit, int recordScanLimit, RecordCursor.NoNextReason noNextReason) {
// Note that this test only requires a database and a context because the ChainedCursor API requires
// a context to be passed in when you are applying scan limits.
FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
try (FDBRecordContext context = database.openContext()) {
ScanProperties props = new ScanProperties(ExecuteProperties.newBuilder().setReturnedRowLimit(returnedRowLimit).setScannedRecordsLimit(recordScanLimit).setFailOnScanLimitReached(false).build());
RecordCursorIterator<Long> cursor = new ChainedCursor<>(context, ChainedCursorTest::nextKey, (key) -> Tuple.from(key).pack(), (prevContinuation) -> Tuple.fromBytes(prevContinuation).getLong(0), null, props).asIterator();
int count = 0;
while (cursor.hasNext()) {
assertEquals(Long.valueOf(count), cursor.next());
++count;
}
assertEquals(Math.min(returnedRowLimit, recordScanLimit), count);
assertEquals(cursor.getNoNextReason(), noNextReason);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext in project fdb-record-layer by FoundationDB.
the class FDBFilterCoalescingQueryTest method simpleRangeCoalesce.
/**
* Validate that a query for all values within a given range on an indexed field will be coalesced
* into a single query on that field.
*/
@DualPlannerTest
public void simpleRangeCoalesce() throws Exception {
complexQuerySetup(NO_HOOK);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("num_value_3_indexed").greaterThanOrEquals(0), Query.field("num_value_3_indexed").lessThanOrEquals(1))).build();
// Index(MySimpleRecord$num_value_3_indexed [[0],[1]])
RecordQueryPlan plan = planner.plan(query);
assertThat(plan, indexScan(allOf(indexName("MySimpleRecord$num_value_3_indexed"), bounds(hasTupleString("[[0],[1]]")))));
assertEquals(1869980849, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(876021686, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-2083489995, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(rec.getRecord());
assertThat(myrec.getNumValue3Indexed(), allOf(greaterThanOrEqualTo(0), lessThanOrEqualTo(1)));
assertThat(myrec.getRecNo() % 5, allOf(greaterThanOrEqualTo(0L), lessThanOrEqualTo(1L)));
i++;
}
}
assertEquals(40, i);
assertDiscardedNone(context);
}
}
use of com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext in project fdb-record-layer by FoundationDB.
the class FDBFilterCoalescingQueryTest method duplicateFilters.
/**
* Verify that the planner removes duplicate filters.
* TODO We currently don't. Update this test when it gets implemented.
* TODO: Some query plans include redundant filtering operations even when the index is a complete specification (https://github.com/FoundationDB/fdb-record-layer/issues/2)
*/
@Test
public void duplicateFilters() throws Exception {
RecordMetaDataHook hook = metaData -> {
metaData.addIndex("MySimpleRecord", new Index("multi_index", "str_value_indexed", "num_value_3_indexed"));
};
complexQuerySetup(hook);
RecordQuery query = RecordQuery.newBuilder().setRecordType("MySimpleRecord").setFilter(Query.and(Query.field("str_value_indexed").equalsValue("even"), Query.field("num_value_3_indexed").equalsValue(3), Query.field("num_value_3_indexed").equalsValue(3))).build();
// Fetch(Covering(Index(multi_index [[even, 3],[even, 3]]) -> [num_value_3_indexed: KEY[1], rec_no: KEY[2], str_value_indexed: KEY[0]]) | num_value_3_indexed EQUALS 3)
RecordQueryPlan plan = planner.plan(query);
assertThat(plan, descendant(coveringIndexScan(indexScan(allOf(indexName("multi_index"), bounds(hasTupleString("[[even, 3],[even, 3]]")))))));
assertEquals(-766201402, plan.planHash(PlanHashable.PlanHashKind.LEGACY));
assertEquals(-1632715349, plan.planHash(PlanHashable.PlanHashKind.FOR_CONTINUATION));
assertEquals(-1418679945, plan.planHash(PlanHashable.PlanHashKind.STRUCTURAL_WITHOUT_LITERALS));
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, hook);
int i = 0;
try (RecordCursorIterator<FDBQueriedRecord<Message>> cursor = recordStore.executeQuery(plan).asIterator()) {
while (cursor.hasNext()) {
FDBQueriedRecord<Message> rec = cursor.next();
TestRecords1Proto.MySimpleRecord.Builder myrec = TestRecords1Proto.MySimpleRecord.newBuilder();
myrec.mergeFrom(rec.getRecord());
assertEquals("even", myrec.getStrValueIndexed());
assertEquals(3, myrec.getNumValue3Indexed());
assertEquals(3, myrec.getRecNo() % 5);
i++;
}
}
assertEquals(10, i);
assertDiscardedNone(context);
}
}
Aggregations