Skip to content

Commit

Permalink
Refactor ticker task to use a thread-safe Set implementation for tick…
Browse files Browse the repository at this point in the history
…ingLocations
  • Loading branch information
md5sha256 authored and StarWishsama committed Sep 6, 2024
1 parent 6e611c1 commit b39097e
Showing 1 changed file with 22 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class TickerTask implements Runnable {

/**
* This Map holds all currently actively ticking locations.
* The value of this map (Set entries) MUST be thread-safe and mutable.
*/
private final Map<ChunkPosition, Set<Location>> tickingLocations = new ConcurrentHashMap<>();

Expand Down Expand Up @@ -255,7 +256,7 @@ public Map<ChunkPosition, Set<Location>> getLocations() {
public Set<Location> getLocations(@Nonnull Chunk chunk) {
Validate.notNull(chunk, "The Chunk cannot be null!");

Set<Location> locations = tickingLocations.getOrDefault(new ChunkPosition(chunk), new HashSet<>());
Set<Location> locations = tickingLocations.getOrDefault(new ChunkPosition(chunk), Collections.emptySet());
return Collections.unmodifiableSet(locations);
}

Expand All @@ -269,11 +270,26 @@ public void enableTicker(@Nonnull Location l) {
Validate.notNull(l, "Location cannot be null!");

synchronized (tickingLocations) {
tickingLocations
.computeIfAbsent(
new ChunkPosition(l.getWorld(), l.getBlockX() >> 4, l.getBlockZ() >> 4),
k -> new HashSet<>())
.add(l);
ChunkPosition chunk = new ChunkPosition(l.getWorld(), l.getBlockX() >> 4, l.getBlockZ() >> 4);

/*
Note that all the values in #tickingLocations must be thread-safe.
Thus, the choice is between the CHM KeySet or a synchronized set.
The CHM KeySet was chosen since it at least permits multiple concurrent
reads without blocking.
*/
Set<Location> newValue = ConcurrentHashMap.newKeySet();
Set<Location> oldValue = tickingLocations.putIfAbsent(chunk, newValue);

/**
* This is faster than doing computeIfAbsent(...)
* on a ConcurrentHashMap because it won't block the Thread for too long
*/
if (oldValue != null) {
oldValue.add(l);
} else {
newValue.add(l);
}
}
}

Expand Down

0 comments on commit b39097e

Please sign in to comment.