@Test public void splitsEventsBackward() { final String stream = generateStreamName(); List<EventData> events = newTestEvents(40); eventstore.appendToStream(stream, ExpectedVersion.NO_STREAM, events).join(); Spliterator<ResolvedEvent> spliterator = new StreamEventsSpliterator( StreamPosition.END, i -> eventstore.readStreamEventsBackward(stream, i, 8, false)); List<ResolvedEvent> result = new ArrayList<>(); range(0, 5) .forEach( i -> { Spliterator<ResolvedEvent> s = spliterator.trySplit(); assertNotNull(s); s.forEachRemaining(result::add); }); assertEquals(40, result.size()); assertNull(spliterator.trySplit()); spliterator.forEachRemaining(e -> fail("Should be no more elements remaining")); assertFalse(spliterator.tryAdvance(result::add)); assertEquals(40, result.size()); assertThat(recordedEventsFrom(result), containsInOrder(reverse(events))); }
@Test public void splitsAndIteratesEventsBackward() { final String stream = generateStreamName(); List<EventData> events = newTestEvents(40); eventstore.appendToStream(stream, ExpectedVersion.NO_STREAM, events).join(); Spliterator<ResolvedEvent> spliterator = new StreamEventsSpliterator( StreamPosition.END, i -> eventstore.readStreamEventsBackward(stream, i, 8, false)); List<ResolvedEvent> result = new ArrayList<>(); Spliterator<ResolvedEvent> s1; s1 = spliterator.trySplit(); assertNotNull(s1); s1.forEachRemaining(result::add); spliterator.forEachRemaining(result::add); assertNull(spliterator.trySplit()); assertEquals(40, result.size()); assertThat(recordedEventsFrom(result), containsInOrder(reverse(events))); }
@Test public void iteratesAndSplitsEventsForward() { final String stream = generateStreamName(); List<EventData> events = newTestEvents(17); eventstore.appendToStream(stream, ExpectedVersion.NO_STREAM, events).join(); Spliterator<ResolvedEvent> spliterator = new StreamEventsSpliterator( StreamPosition.START, i -> eventstore.readStreamEventsForward(stream, i, 5, false)); List<ResolvedEvent> result = new ArrayList<>(); Spliterator<ResolvedEvent> s1, s2, s3; assertTrue(spliterator.tryAdvance(result::add)); s1 = spliterator.trySplit(); assertNotNull(s1); assertTrue(s1.tryAdvance(result::add)); s2 = s1.trySplit(); assertNotNull(s2); assertTrue(s2.tryAdvance(result::add)); s2.forEachRemaining(result::add); assertTrue(s1.tryAdvance(result::add)); s1.forEachRemaining(result::add); assertTrue(spliterator.tryAdvance(result::add)); s3 = spliterator.trySplit(); assertNotNull(s3); assertTrue(s3.tryAdvance(result::add)); s3.forEachRemaining(result::add); assertTrue(spliterator.tryAdvance(result::add)); spliterator.forEachRemaining(result::add); assertNull(spliterator.trySplit()); assertEquals(17, result.size()); assertThat(recordedEventsFrom(result), containsInOrder(events)); }
@Override public Spliterator<R> trySplit() { Spliterator<T> prefix = source.trySplit(); if (prefix == null) return null; Connector<T, R> newBox = new Connector<>(null, none(), this); synchronized (root) { CollapseSpliterator<T, R> result = new CollapseSpliterator<>(root, prefix, left, newBox); this.left = newBox; return result; } }
/** * Overrides AbstractTask version to include checks for early exits while splitting or computing. */ @Override public void compute() { Spliterator<P_IN> rs = spliterator, ls; long sizeEstimate = rs.estimateSize(); long sizeThreshold = getTargetSize(sizeEstimate); boolean forkRight = false; @SuppressWarnings("unchecked") K task = (K) this; AtomicReference<R> sr = sharedResult; R result; while ((result = sr.get()) == null) { if (task.taskCanceled()) { result = task.getEmptyResult(); break; } if (sizeEstimate <= sizeThreshold || (ls = rs.trySplit()) == null) { result = task.doLeaf(); break; } K leftChild, rightChild, taskToFork; task.leftChild = leftChild = task.makeChild(ls); task.rightChild = rightChild = task.makeChild(rs); task.setPendingCount(1); if (forkRight) { forkRight = false; rs = ls; task = leftChild; taskToFork = rightChild; } else { forkRight = true; task = rightChild; taskToFork = leftChild; } taskToFork.fork(); sizeEstimate = rs.estimateSize(); } task.setLocalResult(result); task.tryComplete(); }
@Test public void iteratesAllRemainingEventsForwardWithoutTryAdvanceCall() { final String stream = generateStreamName(); List<EventData> events = newTestEvents(19); eventstore.appendToStream(stream, ExpectedVersion.NO_STREAM, events).join(); Spliterator<ResolvedEvent> spliterator = new StreamEventsSpliterator( StreamPosition.START, i -> eventstore.readStreamEventsForward(stream, i, 17, false)); List<ResolvedEvent> result = new ArrayList<>(); spliterator.forEachRemaining(result::add); assertFalse(spliterator.tryAdvance(result::add)); spliterator.forEachRemaining(e -> fail("Should be no more elements remaining")); assertNull(spliterator.trySplit()); assertEquals(19, result.size()); assertThat(recordedEventsFrom(result), containsInOrder(events)); }