mojang why

This commit is contained in:
Taiyou06
2024-07-14 17:03:49 +03:00
parent 377cdd6a7a
commit b8dd2ddd4c
4 changed files with 526 additions and 0 deletions

View File

@@ -0,0 +1,192 @@
package net.gensokyoreimagined.nitori.common.world.scheduler;
// ChunkTickSchedulerMixin needs this
//import it.unimi.dsi.fastutil.HashCommon;
//import net.minecraft.world.ticks.ScheduledTick;
//
//import java.util.*;
//
//public class OrderedTickQueue<T> extends AbstractQueue<ScheduledTick<T>> {
// private static final int INITIAL_CAPACITY = 16;
// private static final Comparator<ScheduledTick<?>> COMPARATOR = Comparator.comparingLong(ScheduledTick::subTickOrder);
//
// private ScheduledTick<T>[] arr;
//
// private int lastIndexExclusive;
// private int firstIndex;
//
// private long currentMaxSubTickOrder = Long.MIN_VALUE;
// private boolean isSorted;
// private ScheduledTick<T> unsortedPeekResult;
//
// @SuppressWarnings("unchecked")
// public OrderedTickQueue(int capacity) {
// this.arr = (ScheduledTick<T>[]) new ScheduledTick[capacity];
// this.lastIndexExclusive = 0;
// this.isSorted = true;
// this.unsortedPeekResult = null;
// this.firstIndex = 0;
// }
//
// public OrderedTickQueue() {
// this(INITIAL_CAPACITY);
// }
//
// @Override
// public void clear() {
// Arrays.fill(this.arr, null);
// this.lastIndexExclusive = 0;
// this.firstIndex = 0;
// this.currentMaxSubTickOrder = Long.MIN_VALUE;
// this.isSorted = true;
// this.unsortedPeekResult = null;
// }
//
// @Override
// public Iterator<ScheduledTick<T>> iterator() {
// if (this.isEmpty()) {
// return Collections.emptyIterator();
// }
// this.sort();
// return new Iterator<>() {
// int nextIndex = OrderedTickQueue.this.firstIndex;
//
// @Override
// public boolean hasNext() {
// return this.nextIndex < OrderedTickQueue.this.lastIndexExclusive;
// }
//
// @Override
// public ScheduledTick<T> next() {
// return OrderedTickQueue.this.arr[this.nextIndex++];
// }
// };
// }
//
// @Override
// public ScheduledTick<T> poll() {
// if (this.isEmpty()) {
// return null;
// }
// if (!this.isSorted) {
// this.sort();
// }
// ScheduledTick<T> nextTick;
// int polledIndex = this.firstIndex++;
// ScheduledTick<T>[] ticks = this.arr;
// nextTick = ticks[polledIndex];
// ticks[polledIndex] = null;
// return nextTick;
// }
//
// @Override
// public ScheduledTick<T> peek() {
// if (!this.isSorted) {
// return this.unsortedPeekResult;
// } else if (this.lastIndexExclusive > this.firstIndex) {
// return this.getTickAtIndex(this.firstIndex);
// }
// return null;
// }
//
// public boolean offer(ScheduledTick<T> tick) {
// if (this.lastIndexExclusive >= this.arr.length) {
// //todo remove consumed elements first
// this.arr = copyArray(this.arr, HashCommon.nextPowerOfTwo(this.arr.length + 1));
// }
// if (tick.subTickOrder() <= this.currentMaxSubTickOrder) {
// //Set to unsorted instead of slowing down the insertion
// //This is rare but may happen in bulk
// //Sorting later needs O(n*log(n)) time, but it only needs to happen when unordered insertion needs to happen
// //Therefore it is better than n times log(n) time of the PriorityQueue that happens on ordered insertion too
// ScheduledTick<T> firstTick = this.isSorted ? this.size() > 0 ? this.arr[this.firstIndex] : null : this.unsortedPeekResult;
// this.isSorted = false;
// this.unsortedPeekResult = firstTick == null || tick.subTickOrder() < firstTick.subTickOrder() ? tick : firstTick;
// } else {
// this.currentMaxSubTickOrder = tick.subTickOrder();
// }
// this.arr[this.lastIndexExclusive++] = tick;
// return true;
// }
//
// public int size() {
// return this.lastIndexExclusive - this.firstIndex;
// }
//
// private void handleCompaction(int size) {
// // Only compact the array if it is less than 50% filled
// if (this.arr.length > INITIAL_CAPACITY && size < this.arr.length / 2) {
// this.arr = copyArray(this.arr, size);
// } else {
// // Fill the unused array elements with nulls to release our references to the elements in it
// Arrays.fill(this.arr, size, this.arr.length, null);
// }
//
// this.firstIndex = 0;
// this.lastIndexExclusive = size;
//
// if (size == 0 || !this.isSorted) {
// this.currentMaxSubTickOrder = Long.MIN_VALUE;
// } else {
// ScheduledTick<T> tick = this.arr[size - 1];
// this.currentMaxSubTickOrder = tick == null ? Long.MIN_VALUE : tick.subTickOrder();
// }
// }
//
// public void sort() {
// if (this.isSorted) {
// return;
// }
// this.removeNullsAndConsumed();
// Arrays.sort(this.arr, this.firstIndex, this.lastIndexExclusive, COMPARATOR);
// this.isSorted = true;
// this.unsortedPeekResult = null;
// }
//
// public void removeNullsAndConsumed() {
// int src = this.firstIndex;
// int dst = 0;
// while (src < this.lastIndexExclusive) {
// ScheduledTick<T> ScheduledTick = this.arr[src];
// if (ScheduledTick != null) {
// this.arr[dst] = ScheduledTick;
// dst++;
// }
// src++;
// }
// this.handleCompaction(dst);
// }
//
// public ScheduledTick<T> getTickAtIndex(int index) {
// if (!this.isSorted) {
// throw new IllegalStateException("Unexpected access on unsorted queue!");
// }
// return this.arr[index];
// }
//
// public void setTickAtIndex(int index, ScheduledTick<T> tick) {
// if (!this.isSorted) {
// throw new IllegalStateException("Unexpected access on unsorted queue!");
// }
// this.arr[index] = tick;
// }
//
// @SuppressWarnings("unchecked")
// private static <T> ScheduledTick<T>[] copyArray(ScheduledTick<T>[] src, int size) {
// final ScheduledTick<T>[] copy = new ScheduledTick[Math.max(INITIAL_CAPACITY, size)];
//
// if (size != 0) {
// System.arraycopy(src, 0, copy, 0, Math.min(src.length, size));
// }
//
// return copy;
// }
//
// @Override
// public boolean isEmpty() {
// return this.lastIndexExclusive <= this.firstIndex;
// }
//}

View File

@@ -0,0 +1,39 @@
package net.gensokyoreimagined.nitori.mixin.alloc.biome_temprature_leak;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import it.unimi.dsi.fastutil.longs.Long2FloatLinkedOpenHashMap;
import net.minecraft.world.level.biome.Biome;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import java.util.function.Supplier;
@Mixin(Biome.class)
public abstract class Biome_threadLocalMixin {
/*
* Not only do I absolutely hate this garbage cache, cause it barely works at all.
* HOW did nobody at mojang notice that this thread local was not static, how on earth is a non-static private
* value suppose to run on multiple threads at the same time.
* So now its static so that it actually works like its suppose to, and you don't need to declare a billion of them
*
* This is a significant performance boost & reduces a lot of memory usage
*/
private static ThreadLocal<Long2FloatLinkedOpenHashMap> memoryLeakFix$betterTempCache;
@WrapOperation(
method = "<init>",
at = @At(
value = "INVOKE",
target = "Ljava/lang/ThreadLocal;withInitial(Ljava/util/function/Supplier;)Ljava/lang/ThreadLocal;"
)
)
private ThreadLocal<Long2FloatLinkedOpenHashMap> memoryLeakFix$useStaticThreadLocal(Supplier<?> supplier, Operation<ThreadLocal<Long2FloatLinkedOpenHashMap>> original) {
if (memoryLeakFix$betterTempCache == null) {
memoryLeakFix$betterTempCache = original.call(supplier);
}
return memoryLeakFix$betterTempCache;
}
}

View File

@@ -0,0 +1,294 @@
package net.gensokyoreimagined.nitori.mixin.world.tick_scheduler;
//TODO: Make this work with paper
//import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
//import it.unimi.dsi.fastutil.longs.Long2ReferenceAVLTreeMap;
//import it.unimi.dsi.fastutil.objects.ObjectIterator;
//import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
//import net.gensokyoreimagined.nitori.common.world.scheduler.OrderedTickQueue;
//import net.minecraft.nbt.ListTag;
//import net.minecraft.core.BlockPos;
//import net.minecraft.world.ticks.LevelChunkTicks;
//import net.minecraft.world.ticks.ScheduledTick;
//import net.minecraft.world.ticks.SavedTick;
//import net.minecraft.world.ticks.TickPriority;
//import org.jetbrains.annotations.Nullable;
//import org.spongepowered.asm.mixin.*;
//import org.spongepowered.asm.mixin.injection.At;
//import org.spongepowered.asm.mixin.injection.Inject;
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
//
//import java.util.Collection;
//import java.util.List;
//import java.util.Queue;
//import java.util.Set;
//import java.util.function.BiConsumer;
//import java.util.function.Function;
//import java.util.function.Predicate;
//import java.util.stream.Stream;
//
//@Mixin(LevelChunkTicks.class)
//public class ChunkTickSchedulerMixin<T> {
// private static volatile Reference2IntOpenHashMap<Object> TYPE_2_INDEX;
//
// static {
// TYPE_2_INDEX = new Reference2IntOpenHashMap<>();
// TYPE_2_INDEX.defaultReturnValue(-1);
// }
//
// private final Long2ReferenceAVLTreeMap<OrderedTickQueue<T>> tickQueuesByTimeAndPriority = new Long2ReferenceAVLTreeMap<>();
// private OrderedTickQueue<T> nextTickQueue;
// private final IntOpenHashSet allTicks = new IntOpenHashSet();
//
// @Shadow
// private @Nullable BiConsumer<LevelChunkTicks<T>, ScheduledTick<T>> onTickAdded;
//
// @Mutable
// @Shadow
// @Final
// private Set<ScheduledTick<?>> ticksPerPosition;
//
// @Shadow
// private @Nullable List<SavedTick<T>> pendingTicks;
//
// @Mutable
// @Shadow
// @Final
// private Queue<ScheduledTick<T>> tickQueue;
//
// // Paper start - add dirty flag
// private boolean dirty;
// private long lastSaved = Long.MIN_VALUE;
//
// public boolean isDirty(final long tick) {
// return this.dirty || (!this.tickQueue.isEmpty() && tick != this.lastSaved);
// }
//
// public void clearDirty() {
// this.dirty = false;
// }
// // Paper end - add dirty flag
//
// @Inject(
// method = {"<init>()V", "<init>(Ljava/util/List;)V"},
// at = @At("RETURN")
// )
// private void reinit(CallbackInfo ci) {
// //Remove replaced collections
// if (this.pendingTicks != null) {
// for (SavedTick<?> orderedTick : this.pendingTicks) {
// this.allTicks.add(tickToInt(orderedTick.pos(), orderedTick.type()));
// }
// }
// this.ticksPerPosition = null;
// this.tickQueue = null;
// }
//
// private static int tickToInt(BlockPos pos, Object type) {
// //Y coordinate is 12 bits (BlockPos.toLong)
// //X and Z coordinate is 4 bits each (This scheduler is for a single chunk)
// //20 bits are in use for pos
// //12 bits remaining for the type, so up to 4096 different tickable blocks/fluids (not block states) -> can upgrade to long if needed
// int typeIndex = TYPE_2_INDEX.getInt(type);
// if (typeIndex == -1) {
// typeIndex = fixMissingType2Index(type);
// }
//
// int ret = ((pos.getX() & 0xF) << 16) | ((pos.getY() & (0xfff)) << 4) | (pos.getZ() & 0xF);
// ret |= typeIndex << 20;
// return ret;
// }
//
// //This method must be synchronized, otherwise type->int assignments can be overwritten and therefore change
// //Uses clone and volatile store to ensure only fully initialized maps are used, all threads share the same mapping
// private static synchronized int fixMissingType2Index(Object type) {
// //check again, other thread might have replaced the collection
// int typeIndex = TYPE_2_INDEX.getInt(type);
// if (typeIndex == -1) {
// Reference2IntOpenHashMap<Object> clonedType2Index = TYPE_2_INDEX.clone();
// clonedType2Index.put(type, typeIndex = clonedType2Index.size());
// TYPE_2_INDEX = clonedType2Index;
// if (typeIndex >= 4096) {
// throw new IllegalStateException("Lithium Tick Scheduler assumes at most 4096 different block types that receive scheduled ticks exist! Add mixin.world.tick_scheduler=false to the lithium properties/config to disable the optimization!");
// }
// }
// return typeIndex;
// }
//
// /**
// * @author 2No2Name
// * @reason use faster collections
// */
// @Overwrite
// public void schedule(ScheduledTick<T> orderedTick) {
// int intTick = tickToInt(orderedTick.pos(), orderedTick.type());
// if (this.allTicks.add(intTick)) {
// this.dirty = true; // Paper - add dirty flag
// this.scheduleUnchecked(orderedTick);
// }
// }
//
// // Computes a timestamped key including the tick's priority
// // Keys can be sorted in descending order to find what should be executed first
// // 60 time bits, 4 priority bits
// private static long getBucketKey(long time, TickPriority priority) {
// //using priority.ordinal() as is not negative instead of priority.index
// return (time << 4L) | (priority.ordinal() & 15);
// }
//
// private void updateNextTickQueue(boolean checkEmpty) {
// if (checkEmpty && this.nextTickQueue != null && this.nextTickQueue.isEmpty()) {
// OrderedTickQueue<T> removed = this.tickQueuesByTimeAndPriority.remove(this.tickQueuesByTimeAndPriority.firstLongKey());
// if (removed != this.nextTickQueue) {
// throw new IllegalStateException("Next tick queue doesn't have the lowest key!");
// }
// }
// if (this.tickQueuesByTimeAndPriority.isEmpty()) {
// this.nextTickQueue = null;
// return;
// }
// long firstKey = this.tickQueuesByTimeAndPriority.firstLongKey();
// this.nextTickQueue = this.tickQueuesByTimeAndPriority.get(firstKey);
// }
//
// /**
// * @author 2No2Name
// * @reason use faster collections
// */
// @Overwrite
// @Nullable
// public ScheduledTick<T> peek() {
// if (this.nextTickQueue == null) {
// return null;
// }
// return this.nextTickQueue.peek();
// }
//
// /**
// * @author 2No2Name
// * @reason use faster collections
// */
// @Overwrite
// @Nullable
// public ScheduledTick<T> poll() {
// ScheduledTick<T> ScheduledTick = this.nextTickQueue.poll();
// if (ScheduledTick != null) {
// if (this.nextTickQueue.isEmpty()) {
// this.updateNextTickQueue(true);
// }
// this.allTicks.remove(tickToInt(ScheduledTick.pos(), ScheduledTick.type()));
// this.dirty = true; // Paper - add dirty flag
// return ScheduledTick;
// }
// return null;
// }
//
//
// private void scheduleUnchecked(ScheduledTick<T> orderedTick) {
// OrderedTickQueue<T> tickQueue = this.tickQueuesByTimeAndPriority.computeIfAbsent(getBucketKey(orderedTick.triggerTick(), orderedTick.priority()), key -> new OrderedTickQueue<>());
// if (tickQueue.isEmpty()) {
// this.updateNextTickQueue(false);
// }
// tickQueue.offer(orderedTick);
//
// if (this.onTickAdded != null) {
// //noinspection unchecked
// this.onTickAdded.accept((LevelChunkTicks<T>) (Object) this, orderedTick);
// }
// }
//
// /**
// * @author 2No2Name
// * @reason use faster collections
// */
// @Overwrite
// public boolean hasScheduledTick(BlockPos pos, T type) {
// return this.allTicks.contains(tickToInt(pos, type));
// }
//
// /**
// * @author 2No2Name
// * @reason use faster collections
// */
// @Overwrite
// public void removeIf(Predicate<ScheduledTick<T>> predicate) {
// for (ObjectIterator<OrderedTickQueue<T>> tickQueueIterator = this.tickQueuesByTimeAndPriority.values().iterator(); tickQueueIterator.hasNext(); ) {
// OrderedTickQueue<T> nextTickQueue = tickQueueIterator.next();
// nextTickQueue.sort();
// boolean removed = false;
// for (int i = 0; i < nextTickQueue.size(); i++) {
// ScheduledTick<T> nextTick = nextTickQueue.getTickAtIndex(i);
// if (predicate.test(nextTick)) {
// nextTickQueue.setTickAtIndex(i, null);
// this.allTicks.remove(tickToInt(nextTick.pos(), nextTick.type()));
// removed = true;
// }
// }
// if (removed) {
// nextTickQueue.removeNullsAndConsumed();
// }
// if (nextTickQueue.isEmpty()) {
// tickQueueIterator.remove();
// }
// }
// this.updateNextTickQueue(false);
// }
//
// /**
// * @author 2No2Name
// * @reason use faster collections
// */
// @Overwrite
// public Stream<ScheduledTick<T>> getAll() {
// return this.tickQueuesByTimeAndPriority.values().stream().flatMap(Collection::stream);
// }
//
//
// /**
// * @author 2No2Name
// * @reason not use unused field
// */
// @Overwrite
// public int count() {
// return this.allTicks.size();
// }
//
// /**
// * @author 2No2Name
// * @reason not use unused field
// */
// @Overwrite
// public ListTag save(long l, Function<T, String> function) {
// this.lastSaved = l;
// ListTag ListTag = new ListTag();
// if (this.pendingTicks != null) {
// for (SavedTick<T> tick : this.pendingTicks) {
// ListTag.add(tick.save(function));
// }
// }
// for (OrderedTickQueue<T> nextTickQueue : this.tickQueuesByTimeAndPriority.values()) {
// for (ScheduledTick<T> orderedTick : nextTickQueue) {
// ListTag.add(SavedTick.saveTick(orderedTick, function, l));
// }
// }
// return ListTag;
// }
//
//
// /**
// * @author 2No2Name
// * @reason use our datastructures
// */
// @Overwrite
// public void unpack(long time) {
// if (this.pendingTicks != null) {
// int i = -this.pendingTicks.size();
// for (SavedTick<T> tick : this.pendingTicks) {
// this.scheduleUnchecked(tick.unpack(time, i++));
// }
// }
// this.pendingTicks = null;
// }
//}

View File

@@ -31,6 +31,7 @@
"alloc.composter.ComposterMixin$ComposterBlockComposterInventoryMixin",
"alloc.composter.ComposterMixin$ComposterBlockDummyInventoryMixin",
"alloc.composter.ComposterMixin$ComposterBlockFullComposterInventoryMixin",
"alloc.biome_temprature_leak.Biome_threadLocalMixin",
"cached_hashcode.BlockNeighborGroupMixin",
"collections.attributes.AttributeContainerMixin",
"collections.block_entity_tickers.WorldChunkMixin",