package net.minecraft.util.thread; import com.google.common.collect.Queues; import java.util.Locale; import java.util.Queue; import java.util.concurrent.atomic.AtomicInteger; import org.jetbrains.annotations.Nullable; public interface StrictQueue { @Nullable Runnable pop(); boolean push(T task); boolean isEmpty(); int size(); public static final class FixedPriorityQueue implements StrictQueue { private final Queue[] queues; private final AtomicInteger size = new AtomicInteger(); public FixedPriorityQueue(int size) { this.queues = new Queue[size]; for (int i = 0; i < size; i++) { this.queues[i] = Queues.newConcurrentLinkedQueue(); } } @Nullable @Override public Runnable pop() { for (Queue queue : this.queues) { Runnable runnable = (Runnable)queue.poll(); if (runnable != null) { this.size.decrementAndGet(); return runnable; } } return null; } public boolean push(StrictQueue.RunnableWithPriority runnableWithPriority) { int i = runnableWithPriority.priority; if (i < this.queues.length && i >= 0) { this.queues[i].add(runnableWithPriority); this.size.incrementAndGet(); return true; } else { throw new IndexOutOfBoundsException(String.format(Locale.ROOT, "Priority %d not supported. Expected range [0-%d]", i, this.queues.length - 1)); } } @Override public boolean isEmpty() { return this.size.get() == 0; } @Override public int size() { return this.size.get(); } } public static final class QueueStrictQueue implements StrictQueue { private final Queue queue; public QueueStrictQueue(Queue queue) { this.queue = queue; } @Nullable @Override public Runnable pop() { return (Runnable)this.queue.poll(); } @Override public boolean push(Runnable task) { return this.queue.add(task); } @Override public boolean isEmpty() { return this.queue.isEmpty(); } @Override public int size() { return this.queue.size(); } } public record RunnableWithPriority(int priority, Runnable task) implements Runnable { public void run() { this.task.run(); } } }