9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-22 16:29:23 +00:00

possible fix for new NPE

This commit is contained in:
NONPLAYT
2025-04-09 19:59:50 +03:00
parent 0c5e8e2e00
commit 838944a96e
5 changed files with 973 additions and 32 deletions

View File

@@ -22,32 +22,10 @@ index dd2509996bfd08e8c3f9f2be042229eac6d7692d..8ef5a1aaac9c27873ce746eb281f77bb
private static final byte CHUNK_TICKET_STAGE_NONE = 0; private static final byte CHUNK_TICKET_STAGE_NONE = 0;
private static final byte CHUNK_TICKET_STAGE_LOADING = 1; private static final byte CHUNK_TICKET_STAGE_LOADING = 1;
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index d3d9926d504fa6b3384be5ae06b2843ebb7f807c..1d73154786e2ad4c1e9b307dfba43dd6ae008e2a 100644 index d3d9926d504fa6b3384be5ae06b2843ebb7f807c..965899a98223b15bd770378c202873cbf15b714d 100644
--- a/net/minecraft/server/level/ChunkMap.java --- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java
@@ -248,9 +248,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -951,6 +951,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
final ServerPlayer[] backingSet = inRange.getRawDataUnchecked();
- for (int i = 0, len = inRange.size(); i < len; i++) {
- ++(backingSet[i].mobCounts[index]);
+ // DivineMC start - Multithreaded tracker
+ if (org.bxteam.divinemc.DivineConfig.multithreadedEnabled) {
+ for (int i = 0, len = inRange.size(); i < len; i++) {
+ final ServerPlayer player = backingSet[i];
+ if (player == null) continue;
+ ++(player.mobCounts[index]);
+ }
+ } else {
+ for (int i = 0, len = inRange.size(); i < len; i++) {
+ ++(backingSet[i].mobCounts[index]);
+ }
}
+ // DivineMC end - Multithreaded tracker
}
// Paper start - per player mob count backoff
@@ -951,6 +961,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end - optimise entity tracker // Paper end - optimise entity tracker
protected void tick() { protected void tick() {
@@ -61,7 +39,7 @@ index d3d9926d504fa6b3384be5ae06b2843ebb7f807c..1d73154786e2ad4c1e9b307dfba43dd6
// Paper start - optimise entity tracker // Paper start - optimise entity tracker
if (true) { if (true) {
this.newTrackerTick(); this.newTrackerTick();
@@ -1073,7 +1090,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1073,7 +1080,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final Entity entity; final Entity entity;
private final int range; private final int range;
SectionPos lastSectionPos; SectionPos lastSectionPos;
@@ -74,7 +52,7 @@ index d3d9926d504fa6b3384be5ae06b2843ebb7f807c..1d73154786e2ad4c1e9b307dfba43dd6
// Paper start - optimise entity tracker // Paper start - optimise entity tracker
private long lastChunkUpdate = -1L; private long lastChunkUpdate = -1L;
@@ -1100,21 +1121,55 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1100,21 +1111,55 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.lastTrackedChunk = chunk; this.lastTrackedChunk = chunk;
final ServerPlayer[] playersRaw = players.getRawDataUnchecked(); final ServerPlayer[] playersRaw = players.getRawDataUnchecked();
@@ -140,7 +118,7 @@ index d3d9926d504fa6b3384be5ae06b2843ebb7f807c..1d73154786e2ad4c1e9b307dfba43dd6
} }
@Override @Override
@@ -1176,7 +1231,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1176,7 +1221,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} }
public void broadcast(Packet<?> packet) { public void broadcast(Packet<?> packet) {
@@ -149,7 +127,7 @@ index d3d9926d504fa6b3384be5ae06b2843ebb7f807c..1d73154786e2ad4c1e9b307dfba43dd6
serverPlayerConnection.send(packet); serverPlayerConnection.send(packet);
} }
} }
@@ -1189,21 +1244,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1189,21 +1234,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} }
public void broadcastRemoved() { public void broadcastRemoved() {

View File

@@ -964,10 +964,47 @@ index 460bb584db04b582f3297ae419183f430aff1ec0..72c4e1876115745fbeec12fe8a1ad6f4
commands.put(Set.of("fixlight"), new FixLightCommand()); // Paper - rewrite chunk system commands.put(Set.of("fixlight"), new FixLightCommand()); // Paper - rewrite chunk system
commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); // Paper - rewrite chunk system commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); // Paper - rewrite chunk system
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 1d73154786e2ad4c1e9b307dfba43dd6ae008e2a..683a0296fd8b22a9a4a0268075df4f90759e5e8c 100644 index 965899a98223b15bd770378c202873cbf15b714d..dccf4d4b1067e1b09e38cabeae82185929494b62 100644
--- a/net/minecraft/server/level/ChunkMap.java --- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java
@@ -730,27 +730,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -127,8 +127,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public final AtomicInteger tickingGenerated = new AtomicInteger(); // Paper - public
private final String storageName;
private final PlayerMap playerMap = new PlayerMap();
- public final Int2ObjectMap<ChunkMap.TrackedEntity> entityMap = new Int2ObjectOpenHashMap<>();
- private final Long2ByteMap chunkTypeCache = new Long2ByteOpenHashMap();
+ public final Int2ObjectMap<ChunkMap.TrackedEntity> entityMap = new org.bxteam.divinemc.util.map.Int2ObjectConcurrentHashMap<>(); // DivineMC - Chunk System Optimizations
+ private final Long2ByteMap chunkTypeCache = it.unimi.dsi.fastutil.longs.Long2ByteMaps.synchronize(new Long2ByteOpenHashMap()); // DivineMC - Chunk System Optimizations
// Paper - rewrite chunk system
public int serverViewDistance;
public final WorldGenContext worldGenContext; // Paper - public
@@ -249,7 +249,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final ServerPlayer[] backingSet = inRange.getRawDataUnchecked();
for (int i = 0, len = inRange.size(); i < len; i++) {
- ++(backingSet[i].mobCounts[index]);
+ // DivineMC start - Chunk System Optimizations
+ ServerPlayer player = backingSet[i];
+ if (player == null) continue;
+ ++(player.mobCounts[index]);
+ // DivineMC end - Chunk System Optimizations
}
}
@@ -266,7 +270,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
final ServerPlayer[] backingSet = inRange.getRawDataUnchecked();
for (int i = 0, len = inRange.size(); i < len; i++) {
- ++(backingSet[i].mobBackoffCounts[idx]);
+ // DivineMC start - Chunk System Optimizations
+ ServerPlayer player = backingSet[i];
+ if (player == null) continue;
+ ++(player.mobBackoffCounts[idx]);
+ // DivineMC end - Chunk System Optimizations
}
}
// Paper end - per player mob count backoff
@@ -720,27 +728,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return false; return false;
} }
@@ -996,6 +1033,28 @@ index 1d73154786e2ad4c1e9b307dfba43dd6ae008e2a..683a0296fd8b22a9a4a0268075df4f90
// Paper end - chunk tick iteration optimisation // Paper end - chunk tick iteration optimisation
} }
@@ -758,10 +746,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final ServerPlayer[] raw = players.getRawDataUnchecked();
final int len = players.size();
- Objects.checkFromIndexSize(0, len, raw.length);
- for (int i = 0; i < len; ++i) {
+ for (int i = 0; i < raw.length; ++i) { // DivineMC - Chunk System Optimizations
final ServerPlayer player = raw[i];
- if (this.playerIsCloseEnoughForSpawning(player, chunkPos, 16384.0D)) { // Spigot
+ if (player == null) continue; // DivineMC - Chunk System Optimizations
+ if (this.playerIsCloseEnoughForSpawning(player, chunkPos, (org.bxteam.divinemc.DivineConfig.playerNearChunkDetectionRange^2))) { // Spigot // DivineMC - Chunk System Optimizations
if (ret == null) {
ret = new ArrayList<>(len - i);
ret.add(player);
@@ -1146,6 +1134,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} else {
for (int i = 0, len = players.size(); i < len; ++i) {
final ServerPlayer player = playersRaw[i];
+ if (player == null) continue; // DivineMC - Chunk System Optimizations
this.updatePlayer(player);
}
diff --git a/net/minecraft/server/level/DistanceManager.java b/net/minecraft/server/level/DistanceManager.java diff --git a/net/minecraft/server/level/DistanceManager.java b/net/minecraft/server/level/DistanceManager.java
index 5eab6179ce3913cb4e4d424f910ba423faf21c85..4b1efd53e423bdfe90d5efd472823869fc87e73b 100644 index 5eab6179ce3913cb4e4d424f910ba423faf21c85..4b1efd53e423bdfe90d5efd472823869fc87e73b 100644
--- a/net/minecraft/server/level/DistanceManager.java --- a/net/minecraft/server/level/DistanceManager.java

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Optimize canSee checks
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 683a0296fd8b22a9a4a0268075df4f90759e5e8c..65f67bac8ebe2bacd48384675805abb7edd57c6c 100644 index dccf4d4b1067e1b09e38cabeae82185929494b62..55da7420dc3dfff468529a0f101f864dbefe3c7c 100644
--- a/net/minecraft/server/level/ChunkMap.java --- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java
@@ -1259,7 +1259,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -1258,7 +1258,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
flag = flag && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z); flag = flag && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
// Paper end - Configurable entity tracking range by Y // Paper end - Configurable entity tracking range by Y
// CraftBukkit start - respect vanish API // CraftBukkit start - respect vanish API

View File

@@ -0,0 +1,744 @@
package org.bxteam.divinemc.util;
import it.unimi.dsi.fastutil.bytes.ByteIterator;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.IntCollection;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.longs.LongIterator;
import it.unimi.dsi.fastutil.longs.LongListIterator;
import it.unimi.dsi.fastutil.objects.ObjectCollection;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import it.unimi.dsi.fastutil.objects.ReferenceSet;
import it.unimi.dsi.fastutil.shorts.ShortIterator;
import org.apache.commons.lang3.ArrayUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
public final class CollectionWrapperUtil {
private CollectionWrapperUtil() {
throw new IllegalStateException("This class cannot be instantiated");
}
private static <T> Int2ObjectMap.@NotNull Entry<T> intEntryForwards(Map.Entry<Integer, T> entry) {
return new Int2ObjectMap.Entry<>() {
@Override
public T getValue() {
return entry.getValue();
}
@Override
public T setValue(T value) {
return entry.setValue(value);
}
@Override
public int getIntKey() {
return entry.getKey();
}
@Override
public boolean equals(Object obj) {
if (obj == entry) {
return true;
}
return super.equals(obj);
}
@Override
public int hashCode() {
return entry.hashCode();
}
};
}
private static <T> Map.Entry<Integer, T> intEntryBackwards(Int2ObjectMap.Entry<T> entry) {
return entry;
}
public static <T> ObjectSet<Int2ObjectMap.Entry<T>> entrySetIntWrap(Map<Integer, T> map) {
return new ConvertingObjectSet<>(
map.entrySet(),
CollectionWrapperUtil::intEntryForwards,
CollectionWrapperUtil::intEntryBackwards
);
}
public static IntSet wrapIntSet(Set<Integer> intset) {
return new WrappingIntSet(intset);
}
public static ByteIterator itrByteWrap(Iterator<Byte> backing) {
return new WrappingByteIterator(backing);
}
public static ByteIterator itrByteWrap(Iterable<Byte> backing) {
return itrByteWrap(backing.iterator());
}
public static IntIterator itrIntWrap(Iterator<Integer> backing) {
return new WrappingIntIterator(backing);
}
public static IntIterator itrIntWrap(Iterable<Integer> backing) {
return itrIntWrap(backing.iterator());
}
public static LongIterator itrLongWrap(Iterator<Long> backing) {
return new WrappingLongIterator(backing);
}
public static LongIterator itrLongWrap(Iterable<Long> backing) {
return itrLongWrap(backing.iterator());
}
public static ShortIterator itrShortWrap(Iterator<Short> backing) {
return new WrappingShortIterator(backing);
}
public static ShortIterator itrShortWrap(Iterable<Short> backing) {
return itrShortWrap(backing.iterator());
}
public static LongListIterator wrap(ListIterator<Long> c) {
return new WrappingLongListIterator(c);
}
public static LongListIterator wrap(Iterator<Long> c) {
return new SlimWrappingLongListIterator(c);
}
public static <K> ObjectCollection<K> wrap(Collection<K> c) {
return new WrappingObjectCollection<>(c);
}
public static <K> ReferenceSet<K> wrap(Set<K> s) {
return new WrappingRefSet<>(s);
}
public static <T> ObjectIterator<T> itrWrap(Iterable<T> in) {
return new WrapperObjectIterator<>(in.iterator());
}
public static class ConvertingObjectSet<E, T> implements ObjectSet<T> {
private final Set<E> backing;
private final Function<E, T> forward;
private final Function<T, E> back;
public ConvertingObjectSet(Set<E> backing, Function<E, T> forward, Function<T, E> back) {
this.backing = Objects.requireNonNull(backing, "Backing set cannot be null");
this.forward = Objects.requireNonNull(forward, "Forward function cannot be null");
this.back = Objects.requireNonNull(back, "Backward function cannot be null");
}
@Override
public int size() {
return backing.size();
}
@Override
public boolean isEmpty() {
return backing.isEmpty();
}
@SuppressWarnings("unchecked")
@Override
public boolean contains(Object o) {
try {
return backing.contains(back.apply((T) o));
} catch (ClassCastException cce) {
return false;
}
}
@Override
public Object[] toArray() {
return backing.stream().map(forward).toArray();
}
@Override
public <R> R[] toArray(R[] a) {
return backing.stream().map(forward).collect(Collectors.toSet()).toArray(a);
}
@Override
public boolean add(T e) {
return backing.add(back.apply(e));
}
@SuppressWarnings("unchecked")
@Override
public boolean remove(Object o) {
try {
return backing.remove(back.apply((T) o));
} catch (ClassCastException cce) {
return false;
}
}
@SuppressWarnings("unchecked")
@Override
public boolean containsAll(Collection<?> c) {
try {
return backing.containsAll(c.stream()
.map(i -> back.apply((T) i))
.collect(Collectors.toSet()));
} catch (ClassCastException cce) {
return false;
}
}
@Override
public boolean addAll(Collection<? extends T> c) {
return backing.addAll(c.stream().map(back).collect(Collectors.toSet()));
}
@SuppressWarnings("unchecked")
@Override
public boolean removeAll(Collection<?> c) {
try {
return backing.removeAll(c.stream()
.map(i -> back.apply((T) i))
.collect(Collectors.toSet()));
} catch (ClassCastException cce) {
return false;
}
}
@SuppressWarnings("unchecked")
@Override
public boolean retainAll(Collection<?> c) {
try {
return backing.retainAll(c.stream()
.map(i -> back.apply((T) i))
.collect(Collectors.toSet()));
} catch (ClassCastException cce) {
return false;
}
}
@Override
public void clear() {
backing.clear();
}
@Override
public ObjectIterator<T> iterator() {
return new ObjectIterator<>() {
private final Iterator<E> backg = backing.iterator();
@Override
public boolean hasNext() {
return backg.hasNext();
}
@Override
public T next() {
return forward.apply(backg.next());
}
@Override
public void remove() {
backg.remove();
}
};
}
}
static class WrappingIntIterator implements IntIterator {
private final Iterator<Integer> backing;
WrappingIntIterator(Iterator<Integer> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public boolean hasNext() {
return backing.hasNext();
}
@Override
public int nextInt() {
return backing.next();
}
@Override
public Integer next() {
return backing.next();
}
@Override
public void remove() {
backing.remove();
}
}
static class WrappingLongIterator implements LongIterator {
private final Iterator<Long> backing;
WrappingLongIterator(Iterator<Long> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public boolean hasNext() {
return backing.hasNext();
}
@Override
public long nextLong() {
return backing.next();
}
@Override
public Long next() {
return backing.next();
}
@Override
public void remove() {
backing.remove();
}
}
static class WrappingShortIterator implements ShortIterator {
private final Iterator<Short> backing;
WrappingShortIterator(Iterator<Short> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public boolean hasNext() {
return backing.hasNext();
}
@Override
public short nextShort() {
return backing.next();
}
@Override
public Short next() {
return backing.next();
}
@Override
public void remove() {
backing.remove();
}
}
static class WrappingByteIterator implements ByteIterator {
private final Iterator<Byte> backing;
WrappingByteIterator(Iterator<Byte> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public boolean hasNext() {
return backing.hasNext();
}
@Override
public byte nextByte() {
return next();
}
@Override
public Byte next() {
return backing.next();
}
@Override
public void remove() {
backing.remove();
}
}
public static class WrappingIntSet implements IntSet {
private final Set<Integer> backing;
public WrappingIntSet(Set<Integer> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public boolean add(int key) {
return backing.add(key);
}
@Override
public boolean contains(int key) {
return backing.contains(key);
}
@Override
public int[] toIntArray() {
return backing.stream().mapToInt(Integer::intValue).toArray();
}
@Override
public int[] toArray(int[] a) {
return ArrayUtils.toPrimitive(backing.toArray(new Integer[0]));
}
@Override
public boolean addAll(IntCollection c) {
return backing.addAll(c);
}
@Override
public boolean containsAll(IntCollection c) {
return backing.containsAll(c);
}
@Override
public boolean removeAll(IntCollection c) {
return backing.removeAll(c);
}
@Override
public boolean retainAll(IntCollection c) {
return backing.retainAll(c);
}
@Override
public int size() {
return backing.size();
}
@Override
public boolean isEmpty() {
return backing.isEmpty();
}
@Override
public Object[] toArray() {
return backing.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return backing.toArray(a);
}
@Override
public boolean containsAll(Collection<?> c) {
return backing.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends Integer> c) {
return backing.addAll(c);
}
@Override
public boolean removeAll(Collection<?> c) {
return backing.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return backing.retainAll(c);
}
@Override
public void clear() {
backing.clear();
}
@Override
public IntIterator iterator() {
return new WrappingIntIterator(backing.iterator());
}
@Override
public boolean remove(int k) {
return backing.remove(k);
}
}
public static class WrappingRefSet<V> implements ReferenceSet<V> {
private final Set<V> backing;
public WrappingRefSet(Set<V> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public boolean add(V key) {
return backing.add(key);
}
@Override
public boolean remove(final Object o) {
return backing.remove(o);
}
@Override
public boolean containsAll(@NotNull final Collection<?> c) {
return backing.containsAll(c);
}
@Override
public boolean addAll(@NotNull final Collection<? extends V> c) {
return backing.addAll(c);
}
@Override
public boolean removeAll(@NotNull final Collection<?> c) {
return backing.removeAll(c);
}
@Override
public boolean retainAll(@NotNull final Collection<?> c) {
return backing.retainAll(c);
}
@Override
public void clear() {
this.backing.clear();
}
@Override
public int size() {
return backing.size();
}
@Override
public boolean isEmpty() {
return backing.isEmpty();
}
@Override
public boolean contains(final Object o) {
return backing.contains(o);
}
@Override
public ObjectIterator<V> iterator() {
return null;
}
@Override
public @NotNull Object[] toArray() {
return this.backing.toArray();
}
@Override
public @NotNull <T> T[] toArray(@NotNull final T[] a) {
return this.backing.toArray(a);
}
}
public static class WrappingLongListIterator implements LongListIterator {
private final ListIterator<Long> backing;
WrappingLongListIterator(ListIterator<Long> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public long previousLong() {
return backing.previous();
}
@Override
public long nextLong() {
return backing.next();
}
@Override
public boolean hasNext() {
return backing.hasNext();
}
@Override
public boolean hasPrevious() {
return backing.hasPrevious();
}
@Override
public int nextIndex() {
return backing.nextIndex();
}
@Override
public int previousIndex() {
return backing.previousIndex();
}
@Override
public void add(long k) {
backing.add(k);
}
@Override
public void remove() {
backing.remove();
}
@Override
public void set(long k) {
backing.set(k);
}
}
public static class SlimWrappingLongListIterator implements LongListIterator {
private final Iterator<Long> backing;
SlimWrappingLongListIterator(Iterator<Long> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public long previousLong() {
throw new UnsupportedOperationException();
}
@Override
public long nextLong() {
return backing.next();
}
@Override
public boolean hasNext() {
return backing.hasNext();
}
@Override
public boolean hasPrevious() {
throw new UnsupportedOperationException();
}
@Override
public int nextIndex() {
throw new UnsupportedOperationException();
}
@Override
public int previousIndex() {
throw new UnsupportedOperationException();
}
@Override
public void add(long k) {
throw new UnsupportedOperationException();
}
@Override
public void remove() {
backing.remove();
}
@Override
public void set(long k) {
throw new UnsupportedOperationException();
}
}
public static class WrappingObjectCollection<V> implements ObjectCollection<V> {
private final Collection<V> backing;
public WrappingObjectCollection(Collection<V> backing) {
this.backing = Objects.requireNonNull(backing);
}
@Override
public int size() {
return backing.size();
}
@Override
public boolean isEmpty() {
return backing.isEmpty();
}
@Override
public boolean contains(Object o) {
return backing.contains(o);
}
@Override
public Object[] toArray() {
return backing.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return backing.toArray(a);
}
@Override
public boolean add(V e) {
return backing.add(e);
}
@Override
public boolean remove(Object o) {
return backing.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return backing.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends V> c) {
return backing.addAll(c);
}
@Override
public boolean removeAll(Collection<?> c) {
return backing.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return backing.retainAll(c);
}
@Override
public void clear() {
backing.clear();
}
@Override
public ObjectIterator<V> iterator() {
return itrWrap(backing);
}
}
private record WrapperObjectIterator<T>(Iterator<T> parent) implements ObjectIterator<T> {
private WrapperObjectIterator(Iterator<T> parent) {
this.parent = Objects.requireNonNull(parent);
}
@Override
public boolean hasNext() {
return parent.hasNext();
}
@Override
public T next() {
return parent.next();
}
@Override
public void remove() {
parent.remove();
}
}
}

View File

@@ -0,0 +1,160 @@
package org.bxteam.divinemc.util.map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.ObjectCollection;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import org.bxteam.divinemc.util.CollectionWrapperUtil;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public final class Int2ObjectConcurrentHashMap<V> implements Int2ObjectMap<V> {
private final ConcurrentHashMap<Integer, V> backing;
private V defaultReturnValue;
public Int2ObjectConcurrentHashMap() {
this(16);
}
public Int2ObjectConcurrentHashMap(int initialCapacity) {
if (initialCapacity < 0) {
throw new IllegalArgumentException("Initial capacity cannot be negative: " + initialCapacity);
}
this.backing = new ConcurrentHashMap<>(initialCapacity);
}
public Int2ObjectConcurrentHashMap(Map<Integer, V> map) {
this(Math.max(16, map.size()));
putAll(Objects.requireNonNull(map, "Source map cannot be null"));
}
@Override
public V get(int key) {
V value = backing.get(key);
return value != null ? value : defaultReturnValue;
}
@Override
public V get(Object key) {
V value = backing.get(key);
return value != null ? value : defaultReturnValue;
}
@Override
public boolean isEmpty() {
return backing.isEmpty();
}
@Override
public boolean containsValue(Object value) {
return backing.containsValue(value);
}
@Override
public void putAll(Map<? extends Integer, ? extends V> m) {
Objects.requireNonNull(m, "Source map cannot be null");
backing.putAll(m);
}
@Override
public int size() {
return backing.size();
}
@Override
public void defaultReturnValue(V rv) {
this.defaultReturnValue = rv;
}
@Override
public V defaultReturnValue() {
return defaultReturnValue;
}
@Override
public ObjectSet<Entry<V>> int2ObjectEntrySet() {
return CollectionWrapperUtil.entrySetIntWrap(backing);
}
@Override
public IntSet keySet() {
return CollectionWrapperUtil.wrapIntSet(backing.keySet());
}
@Override
public ObjectCollection<V> values() {
return CollectionWrapperUtil.wrap(backing.values());
}
@Override
public boolean containsKey(int key) {
return backing.containsKey(key);
}
@Override
public V put(int key, V value) {
return backing.put(key, value);
}
@Override
public V remove(int key) {
return backing.remove(key);
}
@Override
public void clear() {
backing.clear();
}
public V compute(int key, java.util.function.BiFunction<? super Integer, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
return backing.compute(key, remappingFunction);
}
public ConcurrentHashMap<Integer, V> concurrentView() {
return backing;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Int2ObjectMap<?> that)) return false;
if (size() != that.size()) return false;
return int2ObjectEntrySet().containsAll(that.int2ObjectEntrySet());
}
@Override
public int hashCode() {
return backing.hashCode();
}
@Override
public String toString() {
return backing.toString();
}
public V getOrDefault(int key, V defaultValue) {
V value = get(key);
return value != null ? value : defaultValue;
}
public V putIfAbsent(int key, V value) {
return backing.putIfAbsent(key, value);
}
public boolean remove(int key, Object value) {
return backing.remove(key, value);
}
public boolean replace(int key, V oldValue, V newValue) {
return backing.replace(key, oldValue, newValue);
}
public V replace(int key, V value) {
return backing.replace(key, value);
}
}