Skip to content

Commit

Permalink
fix: use soft/weak references when caching bukkit/P2 worlds (#4439)
Browse files Browse the repository at this point in the history
- Fixes #4435
  • Loading branch information
dordsor21 authored Jun 2, 2024
1 parent 215053e commit be8f07c
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@
import org.bukkit.Bukkit;
import org.checkerframework.checker.nullness.qual.NonNull;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.Map;

public class BukkitWorld implements World<org.bukkit.World> {

private static final Map<String, BukkitWorld> worldMap = Maps.newHashMap();
// Upon world unload we should probably have the P2 BukkitWorld be GCed relatively eagerly, thus freeing the bukkit world.
// We also want to avoid circumstances where a bukkit world has been GCed, but a P2 BukkitWorld has not
private static final Map<String, WeakReference<BukkitWorld>> worldMap = Maps.newHashMap();
private static final boolean HAS_MIN_Y;

static {
Expand All @@ -41,10 +45,11 @@ public class BukkitWorld implements World<org.bukkit.World> {
HAS_MIN_Y = temp;
}

private final org.bukkit.World world;
// We want to allow GC to remove bukkit worlds, but not too eagerly
private final SoftReference<org.bukkit.World> world;

private BukkitWorld(final org.bukkit.World world) {
this.world = world;
this.world = new SoftReference<>(world);
}

/**
Expand All @@ -68,12 +73,13 @@ private BukkitWorld(final org.bukkit.World world) {
* @return World instance
*/
public static @NonNull BukkitWorld of(final org.bukkit.World world) {
BukkitWorld bukkitWorld = worldMap.get(world.getName());
if (bukkitWorld != null && bukkitWorld.getPlatformWorld().equals(world)) {
WeakReference<BukkitWorld> bukkitWorldRef = worldMap.get(world.getName());
BukkitWorld bukkitWorld;
if ((bukkitWorld = bukkitWorldRef.get()) != null && world.equals(bukkitWorld.world.get())) {
return bukkitWorld;
}
bukkitWorld = new BukkitWorld(world);
worldMap.put(world.getName(), bukkitWorld);
worldMap.put(world.getName(), new WeakReference<>(bukkitWorld));
return bukkitWorld;
}

Expand All @@ -97,22 +103,26 @@ public static int getMaxWorldHeight(org.bukkit.World world) {

@Override
public org.bukkit.World getPlatformWorld() {
return this.world;
org.bukkit.World world = this.world.get();
if (world == null) {
throw new IllegalStateException("Bukkit platform world was unloaded from memory");
}
return world;
}

@Override
public @NonNull String getName() {
return this.world.getName();
return this.getPlatformWorld().getName();
}

@Override
public int getMinHeight() {
return getMinWorldHeight(world);
return getMinWorldHeight(getPlatformWorld());
}

@Override
public int getMaxHeight() {
return getMaxWorldHeight(world) - 1;
return getMaxWorldHeight(getPlatformWorld()) - 1;
}

@Override
Expand Down

0 comments on commit be8f07c

Please sign in to comment.