diff --git a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java index acfdabc8f..f5edc3c8f 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -445,7 +445,7 @@ public class IslandCache { } /** - * Get the island by unique id + * Get the island by unique id. The Island will be cached if it is not already. * * @param uniqueId unique id of the Island. * @return island or null if none found @@ -479,6 +479,16 @@ public class IslandCache { return island; } + /** + * Removes the island from the cache to ensure it is reloaded from the database next time. + * @param uniqueId unique id of the Island. + * @return true if the island was in the cache, false otherwise. + * @since 2.4.1 + */ + public boolean expireIslandById(@NonNull String uniqueId) { + return islandsById.containsKey(uniqueId) && islandsById.put(uniqueId, null) != null; + } + /** * Place the island into the cache map * @param island island @@ -540,4 +550,13 @@ public class IslandCache { return this.islandsById.containsKey(uniqueId); } + /** + * Returns if this island is cached. + * @param uniqueId - unique id of island + * @return true if this island is caches, false if not, or if the island is unknown + */ + public boolean isIslandCached(String uniqueId) { + return islandsById.get(uniqueId) != null; + } + } diff --git a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java index 0893a7f09..d7d7b2c43 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java @@ -1,6 +1,7 @@ package world.bentobox.bentobox.managers.island; import java.util.Map.Entry; + import java.util.TreeMap; import world.bentobox.bentobox.database.objects.Island; @@ -33,8 +34,10 @@ class IslandGrid { TreeMap zEntry = grid.get(island.getMinX()); if (zEntry.containsKey(island.getMinZ())) { if (island.getUniqueId().equals(zEntry.get(island.getMinZ()))) { + // If it is the same island then it's okay return true; } + // Island overlap, report error return false; } else { // Add island diff --git a/src/test/java/world/bentobox/bentobox/managers/island/IslandCacheTest.java b/src/test/java/world/bentobox/bentobox/managers/island/IslandCacheTest.java index 2a8410ec7..f99961a4f 100644 --- a/src/test/java/world/bentobox/bentobox/managers/island/IslandCacheTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/island/IslandCacheTest.java @@ -140,7 +140,7 @@ public class IslandCacheTest extends AbstractCommonSetup { // database must be mocked here db = mock(Database.class); - when(db.loadObject(anyString())).thenReturn(island); + when(db.loadObject("uniqueId")).thenReturn(island); when(db.saveObjectAsync(any())).thenReturn(CompletableFuture.completedFuture(true)); // New cache @@ -346,9 +346,13 @@ public class IslandCacheTest extends AbstractCommonSetup { // Fill the cache ic.addIsland(island); ic.setIslandById(island); + assertTrue(ic.isIslandCached("uniqueId")); + // Remove it ic.deleteIslandFromCache(island); - // TODO need to verify + + // verify + assertFalse(ic.isIslandCached("uniqueId")); } /** @@ -466,4 +470,147 @@ public class IslandCacheTest extends AbstractCommonSetup { assertTrue(ic.getIslands(owner).isEmpty()); } + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#addIsland(world.bentobox.bentobox.database.objects.Island)}. + */ + @Test + public void testAddIslandIslandNullWorld() { + // Null world + when(island.getWorld()).thenReturn(null); + assertFalse(ic.addIsland(island)); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#addIsland(world.bentobox.bentobox.database.objects.Island)}. + */ + @Test + public void testAddIslandIslandNullCenter() { + // Try to add an island with a null center + when(island.getCenter()).thenReturn(null); + assertFalse(ic.addIsland(island)); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#addIsland(world.bentobox.bentobox.database.objects.Island)}. + */ + @Test + public void testAddIslandIslandDuplicate() { + assertTrue(ic.addIsland(island)); + assertTrue(ic.addIsland(island)); // Okay to add + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#addIsland(world.bentobox.bentobox.database.objects.Island, boolean)}. + */ + @Test + public void testAddIslandIslandBooleanNullWorld() { + // Null world + when(island.getWorld()).thenReturn(null); + assertFalse(ic.addIsland(island, true)); + assertFalse(ic.isIslandCached("uniqueId")); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#addIsland(world.bentobox.bentobox.database.objects.Island, boolean)}. + */ + @Test + public void testAddIslandIslandBooleanNullCenter() { + // Try to add an island with a null center + when(island.getCenter()).thenReturn(null); + assertFalse(ic.addIsland(island, true)); + assertFalse(ic.isIslandCached("uniqueId")); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#addIsland(world.bentobox.bentobox.database.objects.Island, boolean)}. + */ + @Test + public void testAddIslandIslandBooleanDuplicate() { + // Duplicate + assertTrue(ic.addIsland(island, true)); + assertTrue(ic.addIsland(island, true)); + // Overlapping + Island island2 = mock(Island.class); + when(island2.getUniqueId()).thenReturn("different"); + assertFalse(ic.addIsland(island2, true)); + } + + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#loadIsland(java.lang.String)}. + */ + @Test + public void testLoadIsland() { + assertNull(ic.loadIsland("")); + assertNotNull(ic.loadIsland("uniqueId")); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#getCachedIslands()}. + */ + @Test + public void testGetCachedIslands() { + assertTrue(ic.getCachedIslands().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#getIslandById(java.lang.String)}. + */ + @Test + public void testGetIslandByIdString() { + assertNotNull(ic.getIslandById("uniqueId")); + assertTrue(ic.isIslandCached("uniqueId")); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#getIslandById(java.lang.String, boolean)}. + */ + @Test + public void testGetIslandByIdStringBoolean() { + assertNotNull(ic.getIslandById("uniqueId", false)); + assertFalse(ic.isIslandCached("uniqueId")); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#expireIslandById(java.lang.String)}. + */ + @Test + public void testExpireIslandById() { + // Fill the cache + ic.addIsland(island); + ic.setIslandById(island); + assertTrue(ic.isIslandCached("uniqueId")); + // Remove it + ic.expireIslandById("uniqueId"); + // verify + assertFalse(ic.isIslandCached("uniqueId")); + + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#setIslandById(world.bentobox.bentobox.database.objects.Island)}. + */ + @Test + public void testSetIslandById() { + assertFalse(ic.isIslandId("uniqueId")); + ic.setIslandById(island); + assertTrue(ic.isIslandId("uniqueId")); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#isIslandId(java.lang.String)}. + */ + @Test + public void testIsIslandId() { + assertFalse(ic.isIslandId("uniqueId")); + } + + /** + * Test method for {@link world.bentobox.bentobox.managers.island.IslandCache#isIslandCached(java.lang.String)}. + */ + @Test + public void testIsIslandCached() { + assertFalse(ic.isIslandCached("uniqueId")); + } + }