package org.andork.util;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
public class Batcher3<T> implements Consumer<T> {
private class HandleTask extends TimerTask {
@Override
public void run() {
if (!isBusy.getAsBoolean()) {
timer.cancel();
LinkedList<T> queueToHandle = null;
synchronized (lock) {
if (!queue.isEmpty()) {
queueToHandle = queue;
queue = new LinkedList<>();
}
}
if (queueToHandle != null) {
handler.accept(queueToHandle);
}
}
}
}
private final Object lock = new Object();
private LinkedList<T> queue = new LinkedList<T>();
private int maxSize = Integer.MAX_VALUE;
private BooleanSupplier isBusy;
private Consumer<LinkedList<T>> handler;
private Consumer<T> interruptor;
private Timer timer;
private long delay;
public Batcher3(Consumer<LinkedList<T>> handler, BooleanSupplier isBusy) {
super();
this.handler = handler;
this.isBusy = isBusy;
}
@Override
public void accept(T t) {
synchronized (lock) {
if (queue.size() < maxSize) {
queue.add(t);
}
if (queue.size() == 1) {
timer.scheduleAtFixedRate(new HandleTask(), delay, delay);
}
}
if (interruptor != null) {
interruptor.accept(t);
}
}
public Consumer<T> getInterruptor() {
return interruptor;
}
public int getMaxSize() {
return maxSize;
}
public void setInterruptor(Consumer<T> interruptor) {
this.interruptor = interruptor;
}
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
}