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/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 extends ObjectArrayList { + + private final Comparator comparator; + private boolean binarySearch = true; + + public OrderedComparatorList(int capacity, Comparator comparator) { + super(capacity); + this.comparator = Comparator.nullsLast(comparator); + } + + public OrderedComparatorList(Comparator 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 { + + private final ObjectArrayList 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 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 extends ObjectArrayList { + + 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; + } + +}