com.autonomouslogic.commons.rxjava3.WindowSort Maven / Gradle / Ivy
package com.autonomouslogic.commons.rxjava3;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.FlowableTransformer;
import java.util.ArrayList;
import java.util.Comparator;
import org.reactivestreams.Publisher;
public class WindowSort implements FlowableTransformer {
@lombok.NonNull
private final Comparator comparator;
private final int minWindowSize;
public WindowSort(@lombok.NonNull Comparator comparator, int minWindowSize) {
if (minWindowSize < 1) {
throw new IllegalArgumentException("minWindowSize must be at least 1");
}
this.comparator = comparator;
this.minWindowSize = minWindowSize;
}
@Override
public @NonNull Publisher apply(@NonNull Flowable upstream) {
return Flowable.defer(() -> {
final var window = new ArrayList(minWindowSize * 2);
final var tmp = new ArrayList(minWindowSize);
var sorted = upstream.buffer(minWindowSize)
.flatMap(
buffer -> {
window.addAll(buffer);
window.sort(comparator);
var len = window.size() - minWindowSize;
if (len <= 0) {
return Flowable.empty();
}
var result = new ArrayList<>(window.subList(0, len));
tmp.addAll(window.subList(len, window.size()));
window.clear();
window.addAll(tmp);
tmp.clear();
return Flowable.fromIterable(result);
},
1);
var remaining = Flowable.defer(() -> Flowable.fromIterable(window));
return Flowable.concat(sorted, remaining);
});
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy