From 8fcc22c21d58397c2ae6dcd9ade2c10238cb9c76 Mon Sep 17 00:00:00 2001 From: wizjany Date: Sat, 22 Jun 2019 14:59:46 -0400 Subject: [PATCH] Cleanup multiple batch usage for chunk deletion. --- .../sk89q/worldedit/command/ChunkCommands.java | 16 +++++++++------- .../worldedit/internal/anvil/ChunkDeleter.java | 16 +++++++--------- .../internal/anvil/ChunkDeletionInfo.java | 6 ++++++ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java index 450547740..e9a9e231d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java @@ -133,17 +133,13 @@ public class ChunkCommands { newBatch.worldPath = worldDir.toAbsolutePath().normalize().toString(); newBatch.backup = true; final Region selection = session.getSelection(player.getWorld()); - int chunkCount; if (selection instanceof CuboidRegion) { newBatch.minChunk = BlockVector2.at(selection.getMinimumPoint().getBlockX() >> 4, selection.getMinimumPoint().getBlockZ() >> 4); newBatch.maxChunk = BlockVector2.at(selection.getMaximumPoint().getBlockX() >> 4, selection.getMaximumPoint().getBlockZ() >> 4); - final BlockVector2 dist = newBatch.maxChunk.subtract(newBatch.minChunk).add(1, 1); - chunkCount = dist.getBlockX() * dist.getBlockZ(); } else { // this has a possibility to OOM for very large selections still Set chunks = selection.getChunks(); newBatch.chunks = new ArrayList<>(chunks); - chunkCount = chunks.size(); } if (beforeTime != null) { newBatch.deletionPredicates = new ArrayList<>(); @@ -161,9 +157,15 @@ public class ChunkCommands { throw new StopExecutionException(TextComponent.of("Failed to write chunk list: " + e.getMessage())); } - player.print(String.format("%d chunk(s) have been marked for deletion and will be deleted the next time the server starts.", chunkCount)); - player.print(TextComponent.of("You can mark more chunks for deletion, or to stop the server now, run: ", TextColor.LIGHT_PURPLE) - .append(TextComponent.of("/stop", TextColor.AQUA).clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/stop")))); + player.print(String.format("%d chunk(s) have been marked for deletion the next time the server starts.", + newBatch.getChunkCount())); + if (currentInfo.batches.size() > 1) { + player.printDebug(String.format("%d chunks total marked for deletion. (May have overlaps).", + currentInfo.batches.stream().mapToInt(ChunkDeletionInfo.ChunkBatch::getChunkCount).sum())); + } + player.print(TextComponent.of("You can mark more chunks for deletion, or to stop now, run: ", TextColor.LIGHT_PURPLE) + .append(TextComponent.of("/stop", TextColor.AQUA) + .clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/stop")))); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeleter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeleter.java index 71106c3b3..665210694 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeleter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeleter.java @@ -70,7 +70,7 @@ public final class ChunkDeleter { public static void writeInfo(ChunkDeletionInfo info, Path chunkFile) throws IOException, JsonIOException { String json = chunkDeleterGson.toJson(info, new TypeToken() {}.getType()); - try (BufferedWriter writer = Files.newBufferedWriter(chunkFile, StandardOpenOption.CREATE)) { + try (BufferedWriter writer = Files.newBufferedWriter(chunkFile)) { writer.write(json); } } @@ -130,10 +130,14 @@ public final class ChunkDeleter { } private boolean runBatch(ChunkDeletionInfo.ChunkBatch chunkBatch) { - logger.debug("Processing deletion batch."); + int chunkCount = chunkBatch.getChunkCount(); + logger.debug("Processing deletion batch with {} chunks.", chunkCount); final Map> regionToChunkList = groupChunks(chunkBatch); BiPredicate predicate = createPredicates(chunkBatch.deletionPredicates); shouldPreload = chunkBatch.chunks == null; + deletionsRequested += chunkCount; + debugRate = chunkCount / 10; + return regionToChunkList.entrySet().stream().allMatch(entry -> { Path regionPath = entry.getKey(); if (!Files.exists(regionPath)) return true; @@ -152,8 +156,6 @@ public final class ChunkDeleter { private Map> groupChunks(ChunkDeletionInfo.ChunkBatch chunkBatch) { Path worldPath = Paths.get(chunkBatch.worldPath); if (chunkBatch.chunks != null) { - deletionsRequested += chunkBatch.chunks.size(); - debugRate = chunkBatch.chunks.size() / 10; return chunkBatch.chunks.stream() .collect(Collectors.groupingBy(RegionFilePos::new)) .entrySet().stream().collect(Collectors.toMap( @@ -193,10 +195,6 @@ public final class ChunkDeleter { groupedChunks.put(regionPath, stream); } } - final BlockVector2 dist = maxChunk.subtract(minChunk).add(1, 1); - final int batchSize = dist.getBlockX() * dist.getBlockZ(); - debugRate = batchSize / 10; - this.deletionsRequested += batchSize; return groupedChunks; } } @@ -256,7 +254,7 @@ public final class ChunkDeleter { if (deletionPredicate.test(region, chunk)) { region.deleteChunk(chunk); totalChunksDeleted++; - if (totalChunksDeleted % debugRate == 0) { + if (debugRate != 0 && totalChunksDeleted % debugRate == 0) { logger.debug("Deleted {} chunks so far.", totalChunksDeleted); } } else { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeletionInfo.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeletionInfo.java index 7e03ba502..fcb34ccdc 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeletionInfo.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeletionInfo.java @@ -38,6 +38,12 @@ public class ChunkDeletionInfo { public List chunks; public BlockVector2 minChunk; public BlockVector2 maxChunk; + + public int getChunkCount() { + if (chunks != null) return chunks.size(); + final BlockVector2 dist = maxChunk.subtract(minChunk).add(1, 1); + return dist.getBlockX() * dist.getBlockZ(); + } } public static class DeletionPredicate {