From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: wangxyper Date: Sun, 15 Jan 2023 09:55:30 +0800 Subject: [PATCH] Hearse: Paper util code changes Original license: MIT Original project: https://github.com/Era4FunMC/Hearse diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java index 85f223ffe4414d1dc0653bda260d910dbb8c0f21..a1ac254c71eb5559b88ed1a6bd5128539d3b38b5 100644 --- a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java +++ b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java @@ -1,127 +1,50 @@ package com.destroystokyo.paper.util.maplist; -import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import me.titaniumtown.ArrayConstants; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectList; +import it.unimi.dsi.fastutil.objects.ObjectLists; import net.minecraft.world.entity.Entity; -import java.util.Arrays; +import org.jetbrains.annotations.NotNull; + import java.util.Iterator; -import java.util.NoSuchElementException; -// list with O(1) remove & contains -/** - * @author Spottedleaf - */ public final class EntityList implements Iterable { - - protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); - { - this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); - } - - protected Entity[] entities = ArrayConstants.emptyEntityArray; // Gale - JettPack - reduce array allocations - protected int count; + private final ObjectList entities = ObjectLists.synchronize(new ObjectArrayList<>()); public int size() { - return this.count; + return this.entities.size(); } public boolean contains(final Entity entity) { - return this.entityToIndex.containsKey(entity.getId()); + return this.entities.contains(entity); } public boolean remove(final Entity entity) { - final int index = this.entityToIndex.remove(entity.getId()); - if (index == Integer.MIN_VALUE) { - return false; - } - - // move the entity at the end to this index - final int endIndex = --this.count; - final Entity end = this.entities[endIndex]; - if (index != endIndex) { - // not empty after this call - this.entityToIndex.put(end.getId(), index); // update index - } - this.entities[index] = end; - this.entities[endIndex] = null; - - return true; + return this.entities.remove(entity); } public boolean add(final Entity entity) { - final int count = this.count; - final int currIndex = this.entityToIndex.putIfAbsent(entity.getId(), count); - - if (currIndex != Integer.MIN_VALUE) { - return false; // already in this list - } - - Entity[] list = this.entities; - - if (list.length == count) { - // resize required - list = this.entities = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative - } - - list[count] = entity; - this.count = count + 1; - - return true; + return this.entities.add(entity); } public Entity getChecked(final int index) { - if (index < 0 || index >= this.count) { - throw new IndexOutOfBoundsException("Index: " + index + " is out of bounds, size: " + this.count); - } - return this.entities[index]; + return this.entities.get(index); } public Entity getUnchecked(final int index) { - return this.entities[index]; + return this.entities.get(index); } public Entity[] getRawData() { - return this.entities; + return this.entities.toArray(Entity[]::new); } public void clear() { - this.entityToIndex.clear(); - Arrays.fill(this.entities, 0, this.count, null); - this.count = 0; + this.entities.clear(); } @Override - public Iterator iterator() { - return new Iterator() { - - Entity lastRet; - int current; - - @Override - public boolean hasNext() { - return this.current < EntityList.this.count; - } - - @Override - public Entity next() { - if (this.current >= EntityList.this.count) { - throw new NoSuchElementException(); - } - return this.lastRet = EntityList.this.entities[this.current++]; - } - - @Override - public void remove() { - final Entity lastRet = this.lastRet; - - if (lastRet == null) { - throw new IllegalStateException(); - } - this.lastRet = null; - - EntityList.this.remove(lastRet); - --this.current; - } - }; + public @NotNull Iterator iterator() { + return this.entities.iterator(); } } diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java index a6db66fd143db595802ac91296c607db4867db8e..44bfeb3ccb3c3268cf5696d0c0d6fa6663e0031a 100644 --- a/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java +++ b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java @@ -53,7 +53,7 @@ public final class IBlockDataList { return this.add(getLocationKey(x, y, z), data); } - public long add(final int location, final BlockState data) { + public synchronized long add(final int location, final BlockState data) { final long curr = this.map.get((short)location); if (curr == Long.MAX_VALUE) { @@ -81,7 +81,7 @@ public final class IBlockDataList { return this.remove(getLocationKey(x, y, z)); } - public long remove(final int location) { + public synchronized long remove(final int location) { final long ret = this.map.remove((short)location); final int index = getIndexFromRaw(ret); if (ret == Long.MAX_VALUE) { @@ -101,11 +101,11 @@ public final class IBlockDataList { return ret; } - public int size() { + public synchronized int size() { return this.size; } - public long getRaw(final int index) { + public synchronized long getRaw(final int index) { return this.byIndex[index]; } @@ -117,12 +117,12 @@ public final class IBlockDataList { return getBlockDataFromRaw(this.getRaw(index)); } - public void clear() { + public synchronized void clear() { this.size = 0; this.map.clear(); } - public LongIterator getRawIterator() { + public synchronized LongIterator getRawIterator() { return this.map.values().iterator(); } } diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java index b3329c6fcd6758a781a51f5ba8f5052ac1c77b49..adb02cba6cdb62752f847136000c6f7ca857bd5a 100644 --- a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java +++ b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java @@ -2,9 +2,6 @@ package com.destroystokyo.paper.util.set; import java.util.Collection; -/** - * @author Spottedleaf - */ public final class OptimizedSmallEnumSet> { private final Class enumClass; @@ -20,7 +17,7 @@ public final class OptimizedSmallEnumSet> { this.enumClass = clazz; } - public boolean addUnchecked(final E element) { + public synchronized boolean addUnchecked(final E element) { final int ordinal = element.ordinal(); final long key = 1L << ordinal; @@ -30,7 +27,7 @@ public final class OptimizedSmallEnumSet> { return (prev & key) == 0; } - public boolean removeUnchecked(final E element) { + public synchronized boolean removeUnchecked(final E element) { final int ordinal = element.ordinal(); final long key = 1L << ordinal; @@ -40,15 +37,15 @@ public final class OptimizedSmallEnumSet> { return (prev & key) != 0; } - public void clear() { + public synchronized void clear() { this.backingSet = 0L; } - public int size() { + public synchronized int size() { return Long.bitCount(this.backingSet); } - public void addAllUnchecked(final Collection enums) { + public synchronized void addAllUnchecked(final Collection enums) { for (final E element : enums) { if (element == null) { throw new NullPointerException("Null element"); @@ -57,15 +54,15 @@ public final class OptimizedSmallEnumSet> { } } - public long getBackingSet() { + public synchronized long getBackingSet() { return this.backingSet; } - public boolean hasCommonElements(final OptimizedSmallEnumSet other) { + public synchronized boolean hasCommonElements(final OptimizedSmallEnumSet other) { return (other.backingSet & this.backingSet) != 0; } - public boolean hasElement(final E element) { + public synchronized boolean hasElement(final E element) { return (this.backingSet & (1L << element.ordinal())) != 0; } } diff --git a/src/main/java/io/papermc/paper/util/CachedLists.java b/src/main/java/io/papermc/paper/util/CachedLists.java index e08f4e39db4ee3fed62e37364d17dcc5c5683504..f543462240e744e3424d302eb62be46c70ef9377 100644 --- a/src/main/java/io/papermc/paper/util/CachedLists.java +++ b/src/main/java/io/papermc/paper/util/CachedLists.java @@ -1,57 +1,22 @@ package io.papermc.paper.util; +import com.google.common.collect.Lists; import net.minecraft.world.entity.Entity; import net.minecraft.world.phys.AABB; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.util.UnsafeList; import java.util.List; public final class CachedLists { - - // Paper start - optimise collisions - static final UnsafeList TEMP_COLLISION_LIST = new UnsafeList<>(1024); - static boolean tempCollisionListInUse; - - public static UnsafeList getTempCollisionList() { - if (!Bukkit.isPrimaryThread() || tempCollisionListInUse) { - return new UnsafeList<>(16); - } - tempCollisionListInUse = true; - return TEMP_COLLISION_LIST; - } - - public static void returnTempCollisionList(List list) { - if (list != TEMP_COLLISION_LIST) { - return; - } - ((UnsafeList)list).setSize(0); - tempCollisionListInUse = false; + public static List getTempCollisionList() { + return Lists.newCopyOnWriteArrayList(); } - static final UnsafeList TEMP_GET_ENTITIES_LIST = new UnsafeList<>(1024); - static boolean tempGetEntitiesListInUse; + public static void returnTempCollisionList(List list) {} - public static UnsafeList getTempGetEntitiesList() { - if (!Bukkit.isPrimaryThread() || tempGetEntitiesListInUse) { - return new UnsafeList<>(16); - } - tempGetEntitiesListInUse = true; - return TEMP_GET_ENTITIES_LIST; + public static List getTempGetEntitiesList() { + return Lists.newCopyOnWriteArrayList(); } - public static void returnTempGetEntitiesList(List list) { - if (list != TEMP_GET_ENTITIES_LIST) { - return; - } - ((UnsafeList)list).setSize(0); - tempGetEntitiesListInUse = false; - } - // Paper end - optimise collisions + public static void returnTempGetEntitiesList(List list) {} - public static void reset() { - // Paper start - optimise collisions - TEMP_COLLISION_LIST.completeReset(); - TEMP_GET_ENTITIES_LIST.completeReset(); - // Paper end - optimise collisions - } + public static void reset() {} } diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java index 04c678712f154c2da33e1e38c8583c40f385efed..10d5516378db333023cbc4cc982ef7d2e2c03080 100644 --- a/src/main/java/io/papermc/paper/util/TickThread.java +++ b/src/main/java/io/papermc/paper/util/TickThread.java @@ -1,5 +1,6 @@ package io.papermc.paper.util; +import co.earthme.hearse.concurrent.thread.Worker; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; @@ -75,14 +76,14 @@ public abstract class TickThread extends BaseThread { // Gale - base thread pool } public static boolean isTickThread() { - return Thread.currentThread() instanceof TickThread; + return Thread.currentThread() instanceof TickThread || Thread.currentThread() instanceof Worker; } public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ) { - return Thread.currentThread() instanceof TickThread; + return Thread.currentThread() instanceof TickThread || Thread.currentThread() instanceof Worker; } public static boolean isTickThreadFor(final Entity entity) { - return Thread.currentThread() instanceof TickThread; + return Thread.currentThread() instanceof TickThread || Thread.currentThread() instanceof Worker; } } diff --git a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java index 0fd814f1d65c111266a2b20f86561839a4cef755..fe4d76875462ac9d408c972b968647af78f2ed14 100644 --- a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java +++ b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java @@ -94,7 +94,7 @@ public final class IteratorSafeOrderedReferenceSet { return 1.0 - ((double)this.indexMap.size() / (double)this.listSize); } - public int createRawIterator() { + public synchronized int createRawIterator() { if (this.allowSafeIteration()) { ++this.iteratorCount; } @@ -105,7 +105,7 @@ public final class IteratorSafeOrderedReferenceSet { } } - public int advanceRawIterator(final int index) { + public synchronized int advanceRawIterator(final int index) { final E[] elements = this.listElements; int ret = index + 1; for (int len = this.listSize; ret < len; ++ret) { @@ -117,7 +117,7 @@ public final class IteratorSafeOrderedReferenceSet { return -1; } - public void finishRawIterator() { + public synchronized void finishRawIterator() { if (this.allowSafeIteration() && --this.iteratorCount == 0) { if (this.getFragFactor() >= this.maxFragFactor) { this.defrag(); @@ -125,7 +125,7 @@ public final class IteratorSafeOrderedReferenceSet { } } - public boolean remove(final E element) { + public synchronized boolean remove(final E element) { final int index = this.indexMap.removeInt(element); if (index >= 0) { if (this.firstInvalidIndex < 0 || index < this.firstInvalidIndex) { @@ -144,11 +144,11 @@ public final class IteratorSafeOrderedReferenceSet { return false; } - public boolean contains(final E element) { + public synchronized boolean contains(final E element) { return this.indexMap.containsKey(element); } - public boolean add(final E element) { + public synchronized boolean add(final E element) { final int listSize = this.listSize; final int previous = this.indexMap.putIfAbsent(element, listSize); @@ -223,30 +223,30 @@ public final class IteratorSafeOrderedReferenceSet { //this.check(); } - public E rawGet(final int index) { + public synchronized E rawGet(final int index) { return this.listElements[index]; } - public int size() { + public synchronized int size() { // always returns the correct amount - listSize can be different return this.indexMap.size(); } - public IteratorSafeOrderedReferenceSet.Iterator iterator() { + public synchronized IteratorSafeOrderedReferenceSet.Iterator iterator() { return this.iterator(0); } - public IteratorSafeOrderedReferenceSet.Iterator iterator(final int flags) { + public synchronized IteratorSafeOrderedReferenceSet.Iterator iterator(final int flags) { if (this.allowSafeIteration()) { ++this.iteratorCount; } return new BaseIterator<>(this, true, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); } - public java.util.Iterator unsafeIterator() { + public synchronized java.util.Iterator unsafeIterator() { return this.unsafeIterator(0); } - public java.util.Iterator unsafeIterator(final int flags) { + public synchronized java.util.Iterator unsafeIterator(final int flags) { return new BaseIterator<>(this, false, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); } @@ -273,7 +273,7 @@ public final class IteratorSafeOrderedReferenceSet { } @Override - public boolean hasNext() { + public synchronized boolean hasNext() { if (this.finished) { return false; } @@ -297,7 +297,7 @@ public final class IteratorSafeOrderedReferenceSet { } @Override - public E next() { + public synchronized E next() { if (!this.hasNext()) { throw new NoSuchElementException(); } @@ -310,7 +310,7 @@ public final class IteratorSafeOrderedReferenceSet { } @Override - public void remove() { + public synchronized void remove() { final E lastReturned = this.lastReturned; if (lastReturned == null) { throw new IllegalStateException(); @@ -320,7 +320,7 @@ public final class IteratorSafeOrderedReferenceSet { } @Override - public void finishedIterating() { + public synchronized void finishedIterating() { if (this.finished || !this.canFinish) { throw new IllegalStateException(); }