package org.corfudb.runtime.view.stream;
import lombok.extern.slf4j.Slf4j;
import org.corfudb.protocols.wireprotocol.ILogData;
import org.corfudb.runtime.view.Address;
import java.util.Comparator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
/** A spliterator for streams, which supports limiting the
* spliterator's scope to a maximum global address.
*
* This spliterator is guaranteed to never read PAST the
* maximum global address given. This is necessary because
* reading from a stream MODIFIES the stream pointer, and
* streams provide the guarantee that they will return
* entries in order exactly once.
*
* Concurrent modification of the stream during iteration
* is NOT supported.
*
* Created by mwei on 4/24/17.
*/
@Slf4j
public class StreamSpliterator extends Spliterators.AbstractSpliterator<ILogData> {
/** The stream view which backs the spliterator. */
final IStreamView streamView;
/** The maximum global address the spliterator permits reading up to. */
final long maxGlobal;
/** Construct a stream spliterator with the given view and no limit.
* @param view The view to construct the spliterator with.
*/
public StreamSpliterator(IStreamView view) {
this(view, Address.MAX);
}
/** Construct a stream spliterator with the given view and limit
* @param view The view to construct the spliterator with.
* @param maxGlobal The maximum global address to limit reads up to.
*/
public StreamSpliterator(IStreamView view, long maxGlobal) {
super(maxGlobal - view.getCurrentGlobalPosition(),
Spliterator.ORDERED | Spliterator.SORTED);
streamView = view;
this.maxGlobal = maxGlobal;
}
/** {@inheritDoc} */
@Override
public boolean tryAdvance(Consumer<? super ILogData> action) {
// Get the next entry in the stream.
ILogData next = streamView.nextUpTo(maxGlobal);
// If null, end.
if (next == null) {
return false;
}
// Otherwise, apply
action.accept(next);
return true;
}
/** {@inheritDoc} */
@Override
public Comparator<? super ILogData> getComparator() {
return ILogData::compareTo;
}
}