-
-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
235 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ Original license: GPL v3 | |
Original project: https://github.com/pufferfish-gg/Pufferfish | ||
|
||
Co-authored-by: booky10 <[email protected]> | ||
Co-authored-by: HaHaWTH <[email protected]> | ||
|
||
This patch aims to reduce the main-thread impact of mob spawning by | ||
offloading as much work as possible to other threads. It is possible for | ||
|
@@ -22,9 +23,18 @@ and, in my opinion, worth the low risk of minor mob-spawning-related | |
inconsistencies. | ||
|
||
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java | ||
index c21e00812f1aaa1279834a0562d360d6b89e146c..877d2095a066854939f260ca4b0b8c7b5abb620f 100644 | ||
index c21e00812f1aaa1279834a0562d360d6b89e146c..4ae478c04ef44c91408a7f3f0405291f91794873 100644 | ||
--- a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java | ||
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java | ||
@@ -10,7 +10,7 @@ public final class IteratorSafeOrderedReferenceSet<E> { | ||
public static final int ITERATOR_FLAG_SEE_ADDITIONS = 1 << 0; | ||
|
||
private final Reference2IntLinkedOpenHashMap<E> indexMap; | ||
- private int firstInvalidIndex = -1; | ||
+ private volatile int firstInvalidIndex = -1; // Leaf - Async mob spawning - volatile | ||
|
||
/* list impl */ | ||
private E[] listElements; | ||
@@ -18,7 +18,7 @@ public final class IteratorSafeOrderedReferenceSet<E> { | ||
|
||
private final double maxFragFactor; | ||
|
211 changes: 211 additions & 0 deletions
211
leaf-server/src/main/java/org/dreeam/leaf/util/map/ConcurrentLongHashSet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
package org.dreeam.leaf.util.map; | ||
|
||
import it.unimi.dsi.fastutil.longs.LongCollection; | ||
import it.unimi.dsi.fastutil.longs.LongIterator; | ||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet; | ||
import it.unimi.dsi.fastutil.longs.LongSet; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.Collection; | ||
import java.util.Iterator; | ||
import java.util.Objects; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
/** | ||
* A thread-safe implementation of {@link LongOpenHashSet} using ConcurrentHashMap.KeySetView as backing storage. | ||
* This implementation provides concurrent access and high performance for concurrent operations. | ||
*/ | ||
@SuppressWarnings({"unused", "deprecation"}) | ||
public final class ConcurrentLongHashSet extends LongOpenHashSet implements LongSet { // Extending LongOpenHashSet for some moonrise usages | ||
private final ConcurrentHashMap.KeySetView<Long, Boolean> backing; | ||
|
||
/** | ||
* Creates a new empty concurrent long set. | ||
*/ | ||
public ConcurrentLongHashSet() { | ||
this.backing = ConcurrentHashMap.newKeySet(); | ||
} | ||
|
||
@Override | ||
public int size() { | ||
return backing.size(); | ||
} | ||
|
||
@Override | ||
public boolean isEmpty() { | ||
return backing.isEmpty(); | ||
} | ||
|
||
@Override | ||
public @NotNull LongIterator iterator() { | ||
return new WrappingLongIterator(backing.iterator()); | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public Object @NotNull [] toArray() { | ||
return backing.toArray(); | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public <T> T @NotNull [] toArray(@NotNull T @NotNull [] array) { | ||
Objects.requireNonNull(array, "Array cannot be null"); | ||
return backing.toArray(array); | ||
} | ||
|
||
@Override | ||
public boolean containsAll(@NotNull Collection<?> collection) { | ||
Objects.requireNonNull(collection, "Collection cannot be null"); | ||
return backing.containsAll(collection); | ||
} | ||
|
||
@Override | ||
public boolean addAll(@NotNull Collection<? extends Long> collection) { | ||
Objects.requireNonNull(collection, "Collection cannot be null"); | ||
return backing.addAll(collection); | ||
} | ||
|
||
@Override | ||
public boolean removeAll(@NotNull Collection<?> collection) { | ||
Objects.requireNonNull(collection, "Collection cannot be null"); | ||
return backing.removeAll(collection); | ||
} | ||
|
||
@Override | ||
public boolean retainAll(@NotNull Collection<?> collection) { | ||
Objects.requireNonNull(collection, "Collection cannot be null"); | ||
return backing.retainAll(collection); | ||
} | ||
|
||
@Override | ||
public void clear() { | ||
backing.clear(); | ||
} | ||
|
||
@Override | ||
public boolean add(long key) { | ||
return backing.add(key); | ||
} | ||
|
||
@Override | ||
public boolean contains(long key) { | ||
return backing.contains(key); | ||
} | ||
|
||
@Override | ||
public long[] toLongArray() { | ||
int size = backing.size(); | ||
long[] result = new long[size]; | ||
int i = 0; | ||
for (Long value : backing) { | ||
result[i++] = value; | ||
} | ||
return result; | ||
} | ||
|
||
@Override | ||
public long[] toArray(long[] array) { | ||
Objects.requireNonNull(array, "Array cannot be null"); | ||
long[] result = toLongArray(); | ||
if (array.length < result.length) { | ||
return result; | ||
} | ||
System.arraycopy(result, 0, array, 0, result.length); | ||
if (array.length > result.length) { | ||
array[result.length] = 0; | ||
} | ||
return array; | ||
} | ||
|
||
@Override | ||
public boolean addAll(LongCollection c) { | ||
Objects.requireNonNull(c, "Collection cannot be null"); | ||
boolean modified = false; | ||
LongIterator iterator = c.iterator(); | ||
while (iterator.hasNext()) { | ||
modified |= add(iterator.nextLong()); | ||
} | ||
return modified; | ||
} | ||
|
||
@Override | ||
public boolean containsAll(LongCollection c) { | ||
Objects.requireNonNull(c, "Collection cannot be null"); | ||
LongIterator iterator = c.iterator(); | ||
while (iterator.hasNext()) { | ||
if (!contains(iterator.nextLong())) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean removeAll(LongCollection c) { | ||
Objects.requireNonNull(c, "Collection cannot be null"); | ||
boolean modified = false; | ||
LongIterator iterator = c.iterator(); | ||
while (iterator.hasNext()) { | ||
modified |= remove(iterator.nextLong()); | ||
} | ||
return modified; | ||
} | ||
|
||
@Override | ||
public boolean retainAll(LongCollection c) { | ||
Objects.requireNonNull(c, "Collection cannot be null"); | ||
return backing.retainAll(c); | ||
} | ||
|
||
@Override | ||
public boolean remove(long k) { | ||
return backing.remove(k); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (!(o instanceof LongSet that)) return false; | ||
if (size() != that.size()) return false; | ||
return containsAll(that); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return backing.hashCode(); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return backing.toString(); | ||
} | ||
|
||
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(); | ||
} | ||
} | ||
} |