io.datakernel.datastream.processor.StreamBuffer Maven / Gradle / Ivy
package io.datakernel.datastream.processor;
import io.datakernel.datastream.*;
import io.datakernel.promise.Promise;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Set;
import static io.datakernel.datastream.StreamCapability.IMMEDIATE_SUSPEND;
public class StreamBuffer implements StreamTransformer {
private final Input input;
private final Output output;
private final Deque buffer = new ArrayDeque<>();
private final int minBuffered;
private final int maxBuffered;
private boolean suspended = false; // TODO
// region creators
private StreamBuffer(int minBuffered, int maxBuffered) {
this.minBuffered = minBuffered;
this.maxBuffered = maxBuffered;
this.input = new Input();
this.output = new Output();
}
public static StreamBuffer create() {
return new StreamBuffer<>(0, 0);
}
public static StreamBuffer create(int minBuffered, int maxBuffered) {
return new StreamBuffer<>(minBuffered, maxBuffered);
}
// endregion
protected final class Input extends AbstractStreamConsumer {
@Override
public Set getCapabilities() {
return extendCapabilities(output.getConsumer(), IMMEDIATE_SUSPEND);
}
@Override
protected Promise onEndOfStream() {
output.tryProduce();
return output.getConsumer().getAcknowledgement();
}
@Override
protected void onError(Throwable e) {
output.close(e);
}
}
protected final class Output extends AbstractStreamSupplier implements StreamDataAcceptor {
@Override
public void accept(T item) {
if (suspended) {
buffer.offer(item);
if (buffer.size() >= maxBuffered) {
input.getSupplier().suspend();
}
return;
}
output.getLastDataAcceptor().accept(item);
}
@Override
protected void produce(AsyncProduceController async) {
while (!buffer.isEmpty()) {
if (!output.isReceiverReady()) {
return;
}
send(buffer.pop());
if (buffer.size() < minBuffered) {
input.getSupplier().resume(this);
}
}
if (output.isReceiverReady()) {
suspended = false;
input.getSupplier().resume(this);
}
if (input.getEndOfStream().isResult()) {
sendEndOfStream();
}
}
@Override
protected void onSuspended() {
suspended = true;
if (maxBuffered == 0) {
input.getSupplier().suspend();
}
}
@Override
public Set getCapabilities() {
return extendCapabilities(input.getSupplier(), IMMEDIATE_SUSPEND);
}
@Override
protected void onError(Throwable e) {
input.close(e);
}
}
@Override
public StreamConsumer getInput() {
return input;
}
@Override
public StreamSupplier getOutput() {
return output;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy