2025-11-24 22:52:51 +03:00

92 lines
3.5 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.google.common.collect.Lists
* it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap
* org.jspecify.annotations.Nullable
*/
package net.minecraft.server.level;
import com.google.common.collect.Lists;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import java.util.List;
import java.util.stream.IntStream;
import net.minecraft.server.level.ChunkLevel;
import net.minecraft.world.level.ChunkPos;
import org.jspecify.annotations.Nullable;
public class ChunkTaskPriorityQueue {
public static final int PRIORITY_LEVEL_COUNT = ChunkLevel.MAX_LEVEL + 2;
private final List<Long2ObjectLinkedOpenHashMap<List<Runnable>>> queuesPerPriority = IntStream.range(0, PRIORITY_LEVEL_COUNT).mapToObj(priority -> new Long2ObjectLinkedOpenHashMap()).toList();
private volatile int topPriorityQueueIndex = PRIORITY_LEVEL_COUNT;
private final String name;
public ChunkTaskPriorityQueue(String name) {
this.name = name;
}
protected void resortChunkTasks(int oldPriority, ChunkPos pos, int newPriority) {
if (oldPriority >= PRIORITY_LEVEL_COUNT) {
return;
}
Long2ObjectLinkedOpenHashMap<List<Runnable>> oldQueue = this.queuesPerPriority.get(oldPriority);
List oldTasks = (List)oldQueue.remove(pos.toLong());
if (oldPriority == this.topPriorityQueueIndex) {
while (this.hasWork() && this.queuesPerPriority.get(this.topPriorityQueueIndex).isEmpty()) {
++this.topPriorityQueueIndex;
}
}
if (oldTasks != null && !oldTasks.isEmpty()) {
((List)this.queuesPerPriority.get(newPriority).computeIfAbsent(pos.toLong(), k -> Lists.newArrayList())).addAll(oldTasks);
this.topPriorityQueueIndex = Math.min(this.topPriorityQueueIndex, newPriority);
}
}
protected void submit(Runnable task, long chunkPos, int level) {
((List)this.queuesPerPriority.get(level).computeIfAbsent(chunkPos, p -> Lists.newArrayList())).add(task);
this.topPriorityQueueIndex = Math.min(this.topPriorityQueueIndex, level);
}
protected void release(long pos, boolean unschedule) {
for (Long2ObjectLinkedOpenHashMap<List<Runnable>> queue : this.queuesPerPriority) {
List tasks = (List)queue.get(pos);
if (tasks == null) continue;
if (unschedule) {
tasks.clear();
}
if (!tasks.isEmpty()) continue;
queue.remove(pos);
}
while (this.hasWork() && this.queuesPerPriority.get(this.topPriorityQueueIndex).isEmpty()) {
++this.topPriorityQueueIndex;
}
}
public @Nullable TasksForChunk pop() {
if (!this.hasWork()) {
return null;
}
int index = this.topPriorityQueueIndex;
Long2ObjectLinkedOpenHashMap<List<Runnable>> queue = this.queuesPerPriority.get(index);
long chunkPos = queue.firstLongKey();
List tasks = (List)queue.removeFirst();
while (this.hasWork() && this.queuesPerPriority.get(this.topPriorityQueueIndex).isEmpty()) {
++this.topPriorityQueueIndex;
}
return new TasksForChunk(chunkPos, tasks);
}
public boolean hasWork() {
return this.topPriorityQueueIndex < PRIORITY_LEVEL_COUNT;
}
public String toString() {
return this.name + " " + this.topPriorityQueueIndex + "...";
}
public record TasksForChunk(long chunkPos, List<Runnable> tasks) {
}
}