9
0
mirror of https://github.com/Samsuik/Sakura.git synced 2025-12-22 16:29:16 +00:00
Files
SakuraMC/patches/server/0002-Sakura-Utils.patch
2024-07-15 23:42:56 +01:00

293 lines
9.1 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samsuik <40902469+Samsuik@users.noreply.github.com>
Date: Tue, 23 May 2023 23:07:20 +0100
Subject: [PATCH] Sakura Utils
diff --git a/src/main/java/me/samsuik/sakura/utils/collections/EntityTable.java b/src/main/java/me/samsuik/sakura/utils/collections/EntityTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..54292c693f89ee1444f8b22f4c1488e95ef6bcde
--- /dev/null
+++ b/src/main/java/me/samsuik/sakura/utils/collections/EntityTable.java
@@ -0,0 +1,25 @@
+package me.samsuik.sakura.utils.collections;
+
+import it.unimi.dsi.fastutil.HashCommon;
+import net.minecraft.world.entity.Entity;
+
+public final class EntityTable {
+
+ private final Entity[] entities;
+ private final int mask;
+
+ public EntityTable(int size) {
+ int n = HashCommon.nextPowerOfTwo(size - 1);
+ entities = new Entity[n];
+ mask = n - 1;
+ }
+
+ public Entity locate(Entity entity) {
+ int pos = entity.blockPosition().hashCode();
+ int key = pos & mask;
+ Entity found = entities[key];
+ entities[key] = entity;
+ return found;
+ }
+
+}
diff --git a/src/main/java/me/samsuik/sakura/utils/collections/FixedSizeCustomObjectTable.java b/src/main/java/me/samsuik/sakura/utils/collections/FixedSizeCustomObjectTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..e97f3cc00945f79026af894685d6104dfc920a35
--- /dev/null
+++ b/src/main/java/me/samsuik/sakura/utils/collections/FixedSizeCustomObjectTable.java
@@ -0,0 +1,54 @@
+package me.samsuik.sakura.utils.collections;
+
+import it.unimi.dsi.fastutil.HashCommon;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.function.ToIntFunction;
+
+public final class FixedSizeCustomObjectTable<T> {
+ private final ToIntFunction<T> keyFunction;
+ private final T[] contents;
+ private final int mask;
+
+ public FixedSizeCustomObjectTable(int size, @NotNull ToIntFunction<T> keyFunction) {
+ if (size < 0) {
+ throw new IllegalArgumentException("Table size cannot be negative");
+ } else {
+ int n = HashCommon.nextPowerOfTwo(size - 1);
+ this.keyFunction = keyFunction;
+ this.contents = (T[]) new Object[n];
+ this.mask = (n - 1);
+ }
+ }
+
+ private int key(T value) {
+ return this.keyFunction.applyAsInt(value);
+ }
+
+ public @Nullable T get(T value) {
+ return this.get(this.key(value));
+ }
+
+ public @Nullable T get(int key) {
+ return this.contents[key & this.mask];
+ }
+
+ public void write(int key, T value) {
+ this.contents[key & this.mask] = value;
+ }
+
+ public @Nullable T getAndWrite(T value) {
+ int key = this.key(value);
+ T found = this.get(key);
+ this.write(key, value);
+ return found;
+ }
+
+ public void clear() {
+ int size = this.contents.length;
+ for (int i = 0; i < size; ++i) {
+ this.contents[i] = null;
+ }
+ }
+}
diff --git a/src/main/java/me/samsuik/sakura/utils/collections/OrderedComparatorList.java b/src/main/java/me/samsuik/sakura/utils/collections/OrderedComparatorList.java
new file mode 100644
index 0000000000000000000000000000000000000000..239fc8823b32ae5c8f6e3bfd6ecdde0ccd1e5a8b
--- /dev/null
+++ b/src/main/java/me/samsuik/sakura/utils/collections/OrderedComparatorList.java
@@ -0,0 +1,51 @@
+package me.samsuik.sakura.utils.collections;
+
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+public final class OrderedComparatorList<T> extends ObjectArrayList<T> {
+
+ private final Comparator<T> comparator;
+ private boolean binarySearch = true;
+
+ public OrderedComparatorList(int capacity, Comparator<T> comparator) {
+ super(capacity);
+ this.comparator = Comparator.nullsLast(comparator);
+ }
+
+ public OrderedComparatorList(Comparator<T> comparator) {
+ this(DEFAULT_INITIAL_CAPACITY, comparator);
+ }
+
+ private void validateBounds(int index, T t, boolean up) {
+ if (index != 0 && comparator.compare(get(index - 1), t) > 0) {
+ binarySearch = false;
+ } else if (up && index < size() - 1 && comparator.compare(get(index + 1), t) < 0) {
+ binarySearch = false;
+ }
+ }
+
+ @Override
+ public boolean add(T t) {
+ validateBounds(size(), t, false);
+ return super.add(t);
+ }
+
+ @Override
+ public void add(int index, T t) {
+ validateBounds(index, t, true);
+ super.add(index, t);
+ }
+
+ @Override
+ public int indexOf(final Object k) {
+ if (binarySearch) {
+ return Math.max(Arrays.binarySearch(a, (T) k, comparator), -1);
+ } else {
+ return super.indexOf(k);
+ }
+ }
+
+}
diff --git a/src/main/java/me/samsuik/sakura/utils/collections/TrackedEntityChunkMap.java b/src/main/java/me/samsuik/sakura/utils/collections/TrackedEntityChunkMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..267db86c5d12a804d2f9c868df996a3391910cbd
--- /dev/null
+++ b/src/main/java/me/samsuik/sakura/utils/collections/TrackedEntityChunkMap.java
@@ -0,0 +1,34 @@
+package me.samsuik.sakura.utils.collections;
+
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+import it.unimi.dsi.fastutil.objects.ObjectCollection;
+import net.minecraft.server.level.ChunkMap;
+
+public final class TrackedEntityChunkMap extends Int2ObjectOpenHashMap<ChunkMap.TrackedEntity> {
+
+ private final ObjectArrayList<ChunkMap.TrackedEntity> entityList = new UnorderedIndexedList<>();
+
+ @Override
+ public ChunkMap.TrackedEntity put(int k, ChunkMap.TrackedEntity trackedEntity) {
+ ChunkMap.TrackedEntity tracked = super.put(k, trackedEntity);
+ // bad plugins may replace entries
+ if (tracked != null)
+ entityList.remove(trackedEntity);
+ entityList.add(trackedEntity);
+ return tracked;
+ }
+
+ @Override
+ public ChunkMap.TrackedEntity remove(int k) {
+ ChunkMap.TrackedEntity tracked = super.remove(k);
+ entityList.remove(tracked);
+ return tracked;
+ }
+
+ @Override
+ public ObjectCollection<ChunkMap.TrackedEntity> values() {
+ return entityList;
+ }
+
+}
diff --git a/src/main/java/me/samsuik/sakura/utils/collections/UnorderedIndexedList.java b/src/main/java/me/samsuik/sakura/utils/collections/UnorderedIndexedList.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ca3bf6d6c7aec3a1b31e6ef4f863fa5c34888bd
--- /dev/null
+++ b/src/main/java/me/samsuik/sakura/utils/collections/UnorderedIndexedList.java
@@ -0,0 +1,65 @@
+package me.samsuik.sakura.utils.collections;
+
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+
+public final class UnorderedIndexedList<T> extends ObjectArrayList<T> {
+
+ private final Int2IntOpenHashMap elementToIndex = new Int2IntOpenHashMap();
+
+ {
+ elementToIndex.defaultReturnValue(-1);
+ }
+
+ public UnorderedIndexedList(int capacity) {
+ super(capacity);
+ }
+
+ public UnorderedIndexedList() {
+ super();
+ }
+
+ @Override
+ public boolean add(final T t) {
+ elementToIndex.put(t.hashCode(), size());
+ return super.add(t);
+ }
+
+ @Override
+ public T remove(final int index) {
+ final int tail = size() - 1;
+ final T at = a[index];
+
+ if (index != tail) {
+ final T tailObj = a[tail];
+ if (tailObj != null)
+ elementToIndex.put(tailObj.hashCode(), index);
+ a[index] = tailObj;
+ }
+
+ if (at != null)
+ elementToIndex.remove(at.hashCode());
+ a[tail] = null;
+ size = tail;
+ return at;
+ }
+
+ @Override
+ public void clear() {
+ elementToIndex.clear();
+ super.clear();
+ }
+
+ @Override
+ public int indexOf(final Object k) {
+ if (k == null) return -1;
+ // entities uses their id as a hashcode
+ return elementToIndex.get(k.hashCode());
+ }
+
+ @Override
+ public void add(final int index, final T t) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java b/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java
new file mode 100644
index 0000000000000000000000000000000000000000..93a5655d9dc355d0596c86ea7b592d14ff941476
--- /dev/null
+++ b/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java
@@ -0,0 +1,21 @@
+package me.samsuik.sakura.utils.objects;
+
+public final class Expiry {
+
+ private long expireAt;
+ private final int inc;
+
+ public Expiry(long tick, int inc) {
+ this.expireAt = tick + inc;
+ this.inc = inc;
+ }
+
+ public void refresh(long tick) {
+ this.expireAt = tick + this.inc;
+ }
+
+ public boolean isExpired(long tick) {
+ return tick >= this.expireAt;
+ }
+
+}