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

shz.EtlHelp Maven / Gradle / Ivy

package shz;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Predicate;

public final class EtlHelp {
    private EtlHelp() {
        throw new IllegalStateException();
    }

    /**
     * 生产及消费
     */
    public static  void execute(Consumer> runnable, Consumer> consumer, Predicate filter, int fetchSize) {
        Objects.requireNonNull(runnable);
        Objects.requireNonNull(consumer);
        int permits = fetchSize <= 0 || fetchSize >= Integer.MAX_VALUE >> 1 ? Integer.MAX_VALUE : fetchSize << 1;
        Queue queue = new ConcurrentLinkedQueue<>();
        AtomicReference latch = new AtomicReference<>();
        AtomicBoolean waitFrom = new AtomicBoolean();
        AtomicBoolean waitTo = new AtomicBoolean();
        CompletableFuture future = CompletableFuture.runAsync(() -> {
                    try {
                        runnable.accept(t -> {
                            if (filter != null && !filter.test(t)) return;
                            queue.offer(t);
                            if (waitTo.get() && queue.size() >= permits >>> 1) latch.get().countDown();
                            while (queue.size() >= permits) wait0(latch, waitFrom, waitTo);
                        });
                    } catch (Throwable t) {
                        throw PRException.of(t);
                    } finally {
                        if (waitTo.get()) latch.get().countDown();
                    }
                }
        );
        wait0(latch, waitTo, waitFrom);
        List values = new LinkedList<>();
        while (!future.isDone() && !future.isCancelled()) {
            if (waitFrom.get() && queue.size() <= permits >>> 1) latch.get().countDown();
            while (queue.size() > 0 && values.size() < fetchSize) values.add(queue.remove());
            if (values.size() > 0) {
                consumer.accept(values);
                values.clear();
            } else wait0(latch, waitTo, waitFrom);
        }
        while (queue.size() > 0) values.add(queue.remove());
        if (values.size() > 0) consumer.accept(values);
    }

    private static void wait0(AtomicReference latch, AtomicBoolean wait, AtomicBoolean down) {
        if (down.get()) latch.get().countDown();
        latch.set(new CountDownLatch(1));
        try {
            wait.set(true);
            latch.get().await();
            wait.set(false);
        } catch (InterruptedException e) {
            try {
                TimeUnit.MICROSECONDS.sleep(500L);
            } catch (InterruptedException ignored1) {
            }
        }
    }

    public static  void execute(Consumer> runnable, Consumer> consumer, Predicate filter) {
        execute(runnable, consumer, filter, 2000);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy