All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.autonomouslogic.commons.rxjava3.WindowSort Maven / Gradle / Ivy

There is a newer version: 1.9.2
Show newest version
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