use of com.apple.foundationdb.record.ScanProperties 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.ScanProperties in project fdb-record-layer by FoundationDB.
the class ConcatCursorTest method simpleTimeLimitTest.
@Test
public void simpleTimeLimitTest() {
ScanProperties scanProperties;
// Time limited tests
long maxTimeLimit = 1000;
long timeLimit;
for (timeLimit = 1; timeLimit < maxTimeLimit; timeLimit = timeLimit * 10) {
ep = ExecuteProperties.newBuilder().setTimeLimit(timeLimit).build();
scanProperties = new ScanProperties(ep);
concatTimeLimitTest(scanProperties, timeLimit);
}
}
use of com.apple.foundationdb.record.ScanProperties in project fdb-record-layer by FoundationDB.
the class ConcatCursorTest method simpleRowLimitTest.
@Test
public void simpleRowLimitTest() {
int rowLimit;
// Row limit tests ...
ScanProperties scanProperties;
int maxRows = 51;
for (rowLimit = 0; rowLimit < maxRows; rowLimit++) {
ep = ExecuteProperties.newBuilder().setReturnedRowLimit(rowLimit).build();
scanProperties = new ScanProperties(ep);
if (rowLimit % 2 == 0) {
// toggle between forward and reverse scans
scanProperties.setReverse(true);
} else {
scanProperties.setReverse(false);
}
concatRowLimitTest(scanProperties);
}
}
use of com.apple.foundationdb.record.ScanProperties in project fdb-record-layer by FoundationDB.
the class TextIndexTest method performQueryWithRecordStoreScan.
@Nonnull
private Set<Long> performQueryWithRecordStoreScan(@Nonnull RecordMetaDataHook hook, @Nonnull QueryComponent filter) throws Exception {
final ScanProperties scanProperties = new ScanProperties(ExecuteProperties.newBuilder().setTimeLimit(3000).build());
Set<Long> results = new HashSet<>();
byte[] continuation = null;
do {
try (FDBRecordContext context = openContext()) {
openRecordStore(context);
try (RecordCursor<Long> cursor = recordStore.scanRecords(continuation, scanProperties).filter(record -> record.getRecordType().getName().equals(SIMPLE_DOC)).filter(record -> filter.eval(recordStore, EvaluationContext.EMPTY, record) == Boolean.TRUE).map(record -> record.getPrimaryKey().getLong(0))) {
cursor.forEach(results::add).get();
RecordCursorResult<Long> noNextResult = cursor.getNext();
continuation = noNextResult.getContinuation().toBytes();
}
}
} while (continuation != null);
return results;
}
use of com.apple.foundationdb.record.ScanProperties in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreIndexTest method testIndexOrphanValidationByAutoContinuingCursor.
@Test
public void testIndexOrphanValidationByAutoContinuingCursor() throws Exception {
Set<IndexEntry> expectedInvalidEntries = setUpIndexOrphanValidation();
try (FDBDatabaseRunner runner = fdb.newRunner()) {
AtomicInteger generatorCount = new AtomicInteger();
// Set a scanned records limit to mock when the transaction is out of band.
RecordCursorIterator<InvalidIndexEntry> cursor = new AutoContinuingCursor<>(runner, (context, continuation) -> new LazyCursor<>(FDBRecordStore.newBuilder().setContext(context).setKeySpacePath(path).setMetaDataProvider(simpleMetaData(NO_HOOK)).uncheckedOpenAsync().thenApply(currentRecordStore -> {
generatorCount.getAndIncrement();
final Index index = currentRecordStore.getRecordMetaData().getIndex("MySimpleRecord$str_value_indexed");
ScanProperties scanProperties = new ScanProperties(ExecuteProperties.newBuilder().setReturnedRowLimit(Integer.MAX_VALUE).setIsolationLevel(IsolationLevel.SNAPSHOT).setScannedRecordsLimit(4).build());
return currentRecordStore.getIndexMaintainer(index).validateEntries(continuation, scanProperties);
}))).asIterator();
Set<IndexEntry> results = new HashSet<>();
while (cursor.hasNext()) {
InvalidIndexEntry invalidIndexEntry = cursor.next();
assertEquals(InvalidIndexEntry.Reasons.ORPHAN, invalidIndexEntry.getReason());
IndexEntry entry = invalidIndexEntry.getEntry();
assertFalse(results.contains(entry), "Entry " + entry + " is duplicated");
results.add(entry);
}
assertEquals(expectedInvalidEntries, results, "Validation should return the index entry that has no associated record.");
// The number of scans is about the number of index entries (orphan validation) plus the number of records
// (missing validation).
assertThat(generatorCount.get(), greaterThanOrEqualTo((20 + 10) / 4));
}
}
Aggregations