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 (#4173)

Fixes #3696 Fixes #4216
  • Loading branch information
md5sha256 authored Jan 11, 2025
1 parent 11cea2d commit 755a7eb
Showing 1 changed file with 10 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,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 @@ -329,7 +330,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 @@ -343,7 +344,14 @@ public void enableTicker(@Nonnull Location l) {
Validate.notNull(l, "Location cannot be null!");

ChunkPosition chunk = new ChunkPosition(l.getWorld(), l.getBlockX() >> 4, l.getBlockZ() >> 4);
Set<Location> newValue = new HashSet<>();

/*
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);

/**
Expand Down

0 comments on commit 755a7eb

Please sign in to comment.