diff --git a/src/main/java/world/bentobox/level/LevelsManager.java b/src/main/java/world/bentobox/level/LevelsManager.java index d32bced..9b6d612 100644 --- a/src/main/java/world/bentobox/level/LevelsManager.java +++ b/src/main/java/world/bentobox/level/LevelsManager.java @@ -82,6 +82,8 @@ private boolean addToTopTen(Island island, long lv) { && hasTopTenPerm(island.getWorld(), island.getOwner())) { topTenLists.computeIfAbsent(island.getWorld(), k -> new TopTenData(island.getWorld())).getTopTen() .put(island.getUniqueId(), lv); + // Invalidate the cache for this world because of the update + cache.remove(island.getWorld()); return true; } return false; diff --git a/src/main/java/world/bentobox/level/objects/TopTenData.java b/src/main/java/world/bentobox/level/objects/TopTenData.java index 3d50b1f..ad48bb4 100644 --- a/src/main/java/world/bentobox/level/objects/TopTenData.java +++ b/src/main/java/world/bentobox/level/objects/TopTenData.java @@ -1,8 +1,8 @@ package world.bentobox.level.objects; -import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.bukkit.World; @@ -20,7 +20,7 @@ public class TopTenData { @Expose private String uniqueId = ""; @Expose - private Map topTen = new LinkedHashMap<>(); + private Map topTen = new ConcurrentHashMap<>(); public TopTenData(World k) { uniqueId = k.getName().toLowerCase(Locale.ENGLISH); diff --git a/src/test/java/world/bentobox/level/LevelsManagerTest.java b/src/test/java/world/bentobox/level/LevelsManagerTest.java index ab96e75..c88886c 100644 --- a/src/test/java/world/bentobox/level/LevelsManagerTest.java +++ b/src/test/java/world/bentobox/level/LevelsManagerTest.java @@ -381,6 +381,43 @@ public void testSetIslandLevel() { } + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getTopTen(org.bukkit.World, int)}. + * Verifies that the top ten is sorted in descending order by level. + */ + @Test + public void testGetTopTenSortOrder() { + lm.createAndCleanRankings(world); + Map ttl = lm.getTopTenLists(); + Map tt = ttl.get(world).getTopTen(); + // Add islands in non-sorted order, mimicking the reported issue + String island65 = UUID.randomUUID().toString(); + String island1065 = UUID.randomUUID().toString(); + String island500 = UUID.randomUUID().toString(); + String island200 = UUID.randomUUID().toString(); + // Insert in arbitrary order + tt.put(island65, 65L); + tt.put(island1065, 1065L); + tt.put(island500, 500L); + tt.put(island200, 200L); + when(im.getIslandById(island65)).thenReturn(Optional.of(island)); + when(im.getIslandById(island1065)).thenReturn(Optional.of(island)); + when(im.getIslandById(island500)).thenReturn(Optional.of(island)); + when(im.getIslandById(island200)).thenReturn(Optional.of(island)); + + Map topTen = lm.getTopTen(world, Level.TEN); + // Verify descending order + long previousLevel = Long.MAX_VALUE; + for (Long level : topTen.values()) { + assertTrue("Top ten not in descending order: " + level + " should be <= " + previousLevel, + level <= previousLevel); + previousLevel = level; + } + // Verify highest is first + assertEquals(1065L, topTen.values().iterator().next().longValue()); + } + /** * Test method for * {@link world.bentobox.level.LevelsManager#getRank(World, UUID)}