From 80f0b6f1227bd4d86c44a576904e05dea4cfeaaf Mon Sep 17 00:00:00 2001 From: William Date: Thu, 30 May 2024 02:10:08 +0100 Subject: [PATCH] fix: cache resized claims Also only returns distinct parent claims in `getParentClaimsOverlapping` --- .../huskclaims/claim/ClaimManager.java | 4 +- .../huskclaims/claim/ClaimWorld.java | 45 ++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/net/william278/huskclaims/claim/ClaimManager.java b/common/src/main/java/net/william278/huskclaims/claim/ClaimManager.java index 52a66947..16a5d836 100644 --- a/common/src/main/java/net/william278/huskclaims/claim/ClaimManager.java +++ b/common/src/main/java/net/william278/huskclaims/claim/ClaimManager.java @@ -188,9 +188,9 @@ && getPlugin().getClaimBlocks(claim.getOwner().get()) < neededBlocks) { throw new IllegalArgumentException("Owner does not have enough claim blocks to resize claim"); } - // Update the claim + // Update the claim, resizing it in the claim world context getPlugin().removeMappedClaim(claim, world); - claim.setRegion(newRegion); + world.resizeClaim(claim, newRegion); getDatabase().updateClaimWorld(world); getPlugin().addMappedClaim(claim, world); getPlugin().invalidateClaimListCache(claim.getOwner().orElse(null)); diff --git a/common/src/main/java/net/william278/huskclaims/claim/ClaimWorld.java b/common/src/main/java/net/william278/huskclaims/claim/ClaimWorld.java index 837d809a..0a58eb1c 100644 --- a/common/src/main/java/net/william278/huskclaims/claim/ClaimWorld.java +++ b/common/src/main/java/net/william278/huskclaims/claim/ClaimWorld.java @@ -149,6 +149,10 @@ public void addClaim(@NotNull Claim claim) { * @since 1.0 */ public void removeClaim(@NotNull Claim claim) { + if (claim.isChildClaim()) { + throw new IllegalArgumentException("Cannot remove a child claim directly"); + } + final UUID owner = claim.getOwner().orElse(ADMIN_CLAIM); final Set ownedClaims = userClaims.get(owner); if (ownedClaims != null) { @@ -164,6 +168,40 @@ public void removeClaim(@NotNull Claim claim) { }); } + /** + * Resize a claim in the ClaimWorld, caching the new chunks. + *

+ * It is important that this method is used to resize claims, instead of simply just setting the new claim region, + * as this method ensures that the claim's chunks are correctly cached. + * + * @param claim the claim to resize + * @param newRegion the new region of the claim + * @since 1.3.1 + */ + public void resizeClaim(@NotNull Claim claim, @NotNull Region newRegion) { + if (claim.isChildClaim()) { + throw new IllegalArgumentException("Cannot resize a child claim in a world context"); + } + + // Clear old region chunks + final Region oldRegion = claim.getRegion(); + oldRegion.getChunks().forEach(chunk -> { + final long asLong = ((long) chunk[0] << 32) | (chunk[1] & 0xffffffffL); + final Set chunkClaims = cachedClaims.get(asLong); + if (chunkClaims != null) { + chunkClaims.remove(claim); + } + }); + + // Set new region, cache new chunks + claim.setRegion(newRegion); + newRegion.getChunks().forEach(chunk -> { + final long asLong = ((long) chunk[0] << 32) | (chunk[1] & 0xffffffffL); + final Set chunkClaims = cachedClaims.computeIfAbsent(asLong, k -> Sets.newConcurrentHashSet()); + chunkClaims.add(claim); + }); + } + /** * Returns the name of the ClaimWorld associated with this instance. * @@ -322,7 +360,7 @@ public List getParentClaimsOverlapping(@NotNull Region region) { .filter(claim -> claim.getRegion().overlaps(region)) .forEach(overlappingClaims::add); }); - return overlappingClaims; + return overlappingClaims.stream().distinct().toList(); } /** @@ -428,6 +466,11 @@ private void cacheOwnedClaim(@NotNull Claim claim) { // Cache a claim in the world private void cacheClaim(@NotNull Claim claim) { + if (claim.isChildClaim()) { + throw new IllegalArgumentException("Cannot cache a child claim in a world context"); + } + + // Set parents claim.getChildren().forEach(c -> c.setParent(claim)); cacheOwnedClaim(claim);