use of com.apple.foundationdb.record.RecordCursorResult in project fdb-record-layer by FoundationDB.
the class ProbableIntersectionCursorTest method longLists.
@Test
public void longLists() {
final Random r = new Random(0xba5eba11);
for (int itr = 0; itr < 50; itr++) {
long seed = r.nextLong();
LOGGER.info(KeyValueLogMessage.of("running intersection with large lists", TestLogMessageKeys.SEED, seed, TestLogMessageKeys.ITERATION, itr));
r.setSeed(seed);
final List<List<Integer>> lists = Stream.generate(() -> IntStream.generate(() -> r.nextInt(500)).limit(1000).boxed().collect(Collectors.toList())).limit(5).collect(Collectors.toList());
final List<Function<byte[], RecordCursor<Integer>>> cursorFuncs = lists.stream().map(list -> (Function<byte[], RecordCursor<Integer>>) ((byte[] continuation) -> new RowLimitedCursor<>(RecordCursor.fromList(list, continuation), r.nextInt(50) + 10))).collect(Collectors.toList());
final List<Set<Integer>> sets = lists.stream().map(HashSet::new).collect(Collectors.toList());
final Set<Integer> actualIntersection = new HashSet<>(sets.get(0));
sets.forEach(actualIntersection::retainAll);
Set<Integer> found = new HashSet<>();
AtomicInteger falsePositives = new AtomicInteger();
boolean done = false;
byte[] continuation = null;
while (!done) {
RecordCursor<Integer> intersectionCursor = ProbableIntersectionCursor.create(Collections::singletonList, cursorFuncs, continuation, null);
AsyncUtil.whileTrue(() -> intersectionCursor.onNext().thenApply(result -> {
if (result.hasNext()) {
// Each value should be in at least one set and hopefully all
int value = result.get();
assertThat(sets.stream().anyMatch(set -> set.contains(value)), is(true));
if (!actualIntersection.contains(value)) {
falsePositives.incrementAndGet();
}
found.add(value);
}
return result.hasNext();
}), intersectionCursor.getExecutor()).join();
RecordCursorResult<Integer> result = intersectionCursor.getNext();
assertThat(result.hasNext(), is(false));
if (result.getNoNextReason().isSourceExhausted()) {
done = true;
} else {
assertEquals(RecordCursor.NoNextReason.RETURN_LIMIT_REACHED, result.getNoNextReason());
}
continuation = result.getContinuation().toBytes();
}
assertThat(found.containsAll(actualIntersection), is(true));
LOGGER.info(KeyValueLogMessage.of("intersection false positives", "false_positives", falsePositives.get(), "actual_intersection_size", actualIntersection.size(), "iteration", itr));
assertThat(falsePositives.get(), lessThan(20));
}
}
use of com.apple.foundationdb.record.RecordCursorResult in project fdb-record-layer by FoundationDB.
the class ProbableIntersectionCursorTest method errorInChild.
@Test
public void errorInChild() {
CompletableFuture<Integer> future = new CompletableFuture<>();
RecordCursor<Integer> cursor = ProbableIntersectionCursor.create(Collections::singletonList, Arrays.asList(continuation -> RecordCursor.fromList(Arrays.asList(1, 2), continuation), continuation -> RecordCursor.fromFuture(future)), null, null);
CompletableFuture<RecordCursorResult<Integer>> cursorResultFuture = cursor.onNext();
final RecordCoreException ex = new RecordCoreException("something bad happened!");
future.completeExceptionally(ex);
ExecutionException executionException = assertThrows(ExecutionException.class, cursorResultFuture::get);
assertNotNull(executionException.getCause());
assertSame(ex, executionException.getCause());
}
use of com.apple.foundationdb.record.RecordCursorResult in project fdb-record-layer by FoundationDB.
the class ProbableIntersectionCursorTest method loopIterationWithLimit.
@Test
public void loopIterationWithLimit() throws ExecutionException, InterruptedException {
FDBStoreTimer timer = new FDBStoreTimer();
FirableCursor<Integer> secondCursor = new FirableCursor<>(RecordCursor.fromList(Arrays.asList(2, 1)));
RecordCursor<Integer> cursor = ProbableIntersectionCursor.create(Collections::singletonList, Arrays.asList(continuation -> RecordCursor.fromList(Arrays.asList(1, 2), continuation).limitRowsTo(1), continuation -> secondCursor), null, timer);
CompletableFuture<RecordCursorResult<Integer>> cursorResultFuture = cursor.onNext();
secondCursor.fire();
assertFalse(cursorResultFuture.isDone());
secondCursor.fire();
RecordCursorResult<Integer> cursorResult = cursorResultFuture.get();
assertEquals(1, (int) cursorResult.get());
secondCursor.fire();
cursorResult = cursor.getNext();
assertEquals(RecordCursor.NoNextReason.RETURN_LIMIT_REACHED, cursorResult.getNoNextReason());
assertThat(timer.getCount(FDBStoreTimer.Events.QUERY_INTERSECTION), lessThanOrEqualTo(5));
}
use of com.apple.foundationdb.record.RecordCursorResult in project fdb-record-layer by FoundationDB.
the class UnionIntersectionTest method intersectionMultiReasons.
@Test
public void intersectionMultiReasons() throws Exception {
final Function<byte[], RecordCursor<FDBStoredRecord<Message>>> first = continuation -> scanRecordsBetween(10L, 20L, continuation);
final Function<byte[], RecordCursor<FDBStoredRecord<Message>>> firstLimited = first.andThen(cursor -> new RecordCursorTest.FakeOutOfBandCursor<>(cursor, 3));
final Function<byte[], RecordCursor<FDBStoredRecord<Message>>> second = continuation -> scanRecordsBetween(12L, 17L, continuation);
final Function<byte[], RecordCursor<FDBStoredRecord<Message>>> secondLimited = second.andThen(cursor -> new RecordCursorTest.FakeOutOfBandCursor<>(cursor, 2));
final Function<byte[], RecordCursor<FDBStoredRecord<Message>>> third = continuation -> scanRecordsBetween(13L, 21L, continuation);
final Function<byte[], RecordCursor<FDBStoredRecord<Message>>> thirdLimited = third.andThen(cursor -> cursor.limitRowsTo(2));
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context);
RecordCursor<FDBStoredRecord<Message>> cursor = IntersectionCursor.create(recordStore, comparisonKey, false, Arrays.asList(firstLimited, second, third), null);
assertEquals(Collections.emptyList(), cursor.map(this::storedRecordRecNo).asList().get());
RecordCursorResult<FDBStoredRecord<Message>> noNextResult = cursor.getNext();
assertEquals(RecordCursor.NoNextReason.TIME_LIMIT_REACHED, noNextResult.getNoNextReason());
cursor = IntersectionCursor.create(recordStore, comparisonKey, false, Arrays.asList(firstLimited, secondLimited, thirdLimited), noNextResult.getContinuation().toBytes());
assertEquals(Arrays.asList(13L, 14L), cursor.map(this::storedRecordRecNo).asList().get());
noNextResult = cursor.getNext();
assertEquals(RecordCursor.NoNextReason.RETURN_LIMIT_REACHED, noNextResult.getNoNextReason());
cursor = IntersectionCursor.create(recordStore, comparisonKey, false, Arrays.asList(firstLimited, second, thirdLimited), noNextResult.getContinuation().toBytes());
assertEquals(Arrays.asList(15L, 16L), cursor.map(this::storedRecordRecNo).asList().get());
noNextResult = cursor.getNext();
assertEquals(RecordCursor.NoNextReason.SOURCE_EXHAUSTED, noNextResult.getNoNextReason());
}
}
use of com.apple.foundationdb.record.RecordCursorResult in project fdb-record-layer by FoundationDB.
the class UnionIntersectionTest method nonIntersectingReasons.
@Test
public void nonIntersectingReasons() {
final List<Integer> leftList = Arrays.asList(0, 2, 4, 6);
final Function<byte[], RecordCursor<Integer>> left = continuation -> RecordCursor.fromList(leftList, continuation).limitRowsTo(1);
final List<Integer> rightList = Arrays.asList(1, 3, 5, 7);
final Function<byte[], RecordCursor<Integer>> right = continuation -> RecordCursor.fromList(rightList, continuation).limitRowsTo(1);
FDBStoreTimer timer = new FDBStoreTimer();
boolean done = false;
byte[] continuation = null;
List<Integer> results = new ArrayList<>();
while (!done) {
IntersectionCursor<Integer> intersectionCursor = IntersectionCursor.create(Collections::singletonList, false, left, right, continuation, timer);
intersectionCursor.forEach(results::add).join();
RecordCursorResult<Integer> noNextResult = intersectionCursor.getNext();
done = noNextResult.getNoNextReason().isSourceExhausted();
continuation = noNextResult.getContinuation().toBytes();
if (!done) {
assertEquals(RecordCursor.NoNextReason.RETURN_LIMIT_REACHED, noNextResult.getNoNextReason());
}
}
assertEquals(Collections.emptyList(), results);
System.out.println(timer.getKeysAndValues());
}
Aggregations