Skip to content

Commit 6766c0f

Browse files
committed
Store the island sizes in the grid to avoid database loadings #2534
1 parent e0a3f48 commit 6766c0f

File tree

4 files changed

+74
-83
lines changed

4 files changed

+74
-83
lines changed

src/main/java/world/bentobox/bentobox/managers/IslandsManager.java

+4
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ public Optional<Island> getIslandAt(@NonNull Location location) {
442442
: Optional.empty();
443443
}
444444

445+
public boolean isIslandAd(@NonNull Location location) {
446+
return plugin.getIWM().inWorld(location) ? islandCache.isIslandAt(location) : false;
447+
}
448+
445449
/**
446450
* Returns an <strong>unmodifiable collection</strong> of all existing islands
447451
* (even those who may be unowned).

src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java

+17
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,23 @@ public void setPrimaryIsland(@NonNull UUID uuid, @NonNull Island island) {
257257
}
258258
}
259259

260+
/**
261+
* Returns if there is island at the location. This includes
262+
* the full island space, not just the protected area.
263+
* Does not cause a database load of the island.
264+
*
265+
* @param location the location
266+
* @return true if there is an island there
267+
*/
268+
@Nullable
269+
public boolean isIslandAt(@NonNull Location location) {
270+
World w = Util.getWorld(location.getWorld());
271+
if (w == null || !grids.containsKey(w)) {
272+
return false;
273+
}
274+
return grids.get(w).isIslandAt(location.getBlockX(), location.getBlockZ());
275+
}
276+
260277
/**
261278
* Returns the island at the location or null if there is none. This includes
262279
* the full island space, not just the protected area

src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java

+53-24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.util.Map.Entry;
44
import java.util.TreeMap;
55

6+
import org.eclipse.jdt.annotation.Nullable;
7+
68
import world.bentobox.bentobox.database.objects.Island;
79

810
/**
@@ -11,7 +13,11 @@
1113
*
1214
*/
1315
class IslandGrid {
14-
private final TreeMap<Integer, TreeMap<Integer, String>> grid = new TreeMap<>();
16+
17+
private record IslandData(String id, int minX, int minZ, int range) {
18+
}
19+
20+
private final TreeMap<Integer, TreeMap<Integer, IslandData>> grid = new TreeMap<>();
1521
private final IslandCache im;
1622

1723
/**
@@ -29,25 +35,28 @@ public IslandGrid(IslandCache im) {
2935
*/
3036
public boolean addToGrid(Island island) {
3137
// Check if we know about this island already
32-
if (grid.containsKey(island.getMinX())) {
33-
TreeMap<Integer, String> zEntry = grid.get(island.getMinX());
34-
if (zEntry.containsKey(island.getMinZ())) {
35-
if (island.getUniqueId().equals(zEntry.get(island.getMinZ()))) {
38+
int minX = island.getMinX();
39+
int minZ = island.getMinZ();
40+
IslandData islandData = new IslandData(island.getUniqueId(), minZ, minZ, island.getRange());
41+
if (grid.containsKey(minX)) {
42+
TreeMap<Integer, IslandData> zEntry = grid.get(minX);
43+
if (zEntry.containsKey(minZ)) {
44+
if (island.getUniqueId().equals(zEntry.get(minZ).id())) {
3645
// If it is the same island then it's okay
3746
return true;
3847
}
3948
// Island overlap, report error
4049
return false;
4150
} else {
4251
// Add island
43-
zEntry.put(island.getMinZ(), island.getUniqueId());
44-
grid.put(island.getMinX(), zEntry);
52+
zEntry.put(minZ, islandData);
53+
grid.put(minX, zEntry);
4554
}
4655
} else {
4756
// Add island
48-
TreeMap<Integer, String> zEntry = new TreeMap<>();
49-
zEntry.put(island.getMinZ(), island.getUniqueId());
50-
grid.put(island.getMinX(), zEntry);
57+
TreeMap<Integer, IslandData> zEntry = new TreeMap<>();
58+
zEntry.put(minZ, islandData);
59+
grid.put(minX, zEntry);
5160
}
5261
return true;
5362
}
@@ -60,7 +69,7 @@ public boolean addToGrid(Island island) {
6069
public boolean removeFromGrid(Island island) {
6170
String id = island.getUniqueId();
6271
boolean removed = grid.values().stream()
63-
.anyMatch(innerMap -> innerMap.values().removeIf(innerValue -> innerValue.equals(id)));
72+
.anyMatch(innerMap -> innerMap.values().removeIf(innerValue -> innerValue.id().equals(id)));
6473

6574
grid.values().removeIf(TreeMap::isEmpty);
6675

@@ -70,35 +79,55 @@ public boolean removeFromGrid(Island island) {
7079
/**
7180
* Retrieves the island located at the specified x and z coordinates, covering both the protected area
7281
* and the full island space. Returns null if no island exists at the given location.
82+
* This will load the island from the database if it is not in the cache.
7383
*
7484
* @param x the x coordinate of the location
7585
* @param z the z coordinate of the location
7686
* @return the Island at the specified location, or null if no island is found
7787
*/
7888
public Island getIslandAt(int x, int z) {
89+
String id = getIslandStringAt(x, z);
90+
if (id == null) {
91+
return null;
92+
}
93+
94+
// Retrieve the island using the id found - loading from database if required
95+
return im.getIslandById(id);
96+
}
97+
98+
/**
99+
* Checks if an island is at this coordinate or not
100+
* @param x coord
101+
* @param z coord
102+
* @return true if there is an island registered in the grid
103+
*/
104+
public boolean isIslandAt(int x, int z) {
105+
return getIslandStringAt(x, z) != null;
106+
}
107+
108+
/**
109+
* Get the island ID string for an island at this coordinates, or null if none.
110+
* @param x coord
111+
* @param z coord
112+
* @return Unique Island ID string, or null if there is no island here.
113+
*/
114+
public @Nullable String getIslandStringAt(int x, int z) {
79115
// Attempt to find the closest x-coordinate entry that does not exceed 'x'
80-
Entry<Integer, TreeMap<Integer, String>> xEntry = grid.floorEntry(x);
116+
Entry<Integer, TreeMap<Integer, IslandData>> xEntry = grid.floorEntry(x);
81117
if (xEntry == null) {
82118
return null; // No x-coordinate entry found, return null
83119
}
84120

85121
// Attempt to find the closest z-coordinate entry that does not exceed 'z' within the found x-coordinate
86-
Entry<Integer, String> zEntry = xEntry.getValue().floorEntry(z);
122+
Entry<Integer, IslandData> zEntry = xEntry.getValue().floorEntry(z);
87123
if (zEntry == null) {
88124
return null; // No z-coordinate entry found, return null
89125
}
90-
91-
// Retrieve the island using the id found in the z-coordinate entry
92-
Island island = im.getIslandById(zEntry.getValue());
93-
if (island == null) {
94-
return null; // No island found by the id, return null
95-
}
96126
// Check if the specified coordinates are within the island space
97-
if (island.inIslandSpace(x, z)) {
98-
return island; // Coordinates are within island space, return the island
127+
if (x >= zEntry.getValue().minX() && x < zEntry.getValue().minX() + zEntry.getValue().range() * 2
128+
&& z >= zEntry.getValue().minZ() && z < zEntry.getValue().minZ() + zEntry.getValue().range() * 2) {
129+
return zEntry.getValue().id();
99130
}
100-
101-
// Coordinates are outside the island space, return null
102131
return null;
103132
}
104133

@@ -107,7 +136,7 @@ public Island getIslandAt(int x, int z) {
107136
*/
108137
public long getSize() {
109138
long count = 0;
110-
for (TreeMap<Integer, String> innerMap : grid.values()) {
139+
for (TreeMap<Integer, IslandData> innerMap : grid.values()) {
111140
count += innerMap.size();
112141
}
113142
return count;

src/main/java/world/bentobox/bentobox/panels/customizable/SettingsPanel.java

-59
This file was deleted.

0 commit comments

Comments
 (0)