more efficient plot diff calculations

This commit is contained in:
boy0001 2015-04-01 11:52:22 +11:00
parent 3477132cf2
commit 8b62ba9d65
5 changed files with 96 additions and 53 deletions

View File

@ -22,7 +22,6 @@ package com.intellectualcrafters.plot.database;
import java.io.File;
import java.io.IOException;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

View File

@ -1,8 +1,11 @@
package com.intellectualcrafters.plot.generator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.lang.mutable.MutableInt;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
@ -13,14 +16,82 @@ import com.intellectualcrafters.plot.BukkitMain;
import com.intellectualcrafters.plot.PlotSquared;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.bukkit.BukkitSetBlockManager;
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
public class BukkitHybridUtils extends HybridUtils {
public void checkModified(final Plot plot, final int requiredChanges, final Runnable whenDone) {
TaskManager.index.increment();
final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1);
final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id);
int bx = bot.getX() >> 4;
int bz = bot.getZ() >> 4;
int tx = top.getX() >> 4;
int tz = top.getZ() >> 4;
int size = (tx-bx) << 4;
World world = BukkitUtil.getWorld(plot.world);
final HashSet<Chunk> chunks = new HashSet<>();
for (int X = bx; X <= tx; X++) {
for (int Z = bz; Z <= tz; Z++) {
chunks.add(world.getChunkAt(X,Z));
}
}
PlotWorld plotworld = PlotSquared.getPlotWorld(plot.world);
if (!(plotworld instanceof ClassicPlotWorld)) {
TaskManager.runTaskLater(whenDone, 1);
return;
}
final ClassicPlotWorld cpw = (ClassicPlotWorld) plotworld;
final MutableInt count = new MutableInt(0);
final Integer currentIndex = TaskManager.index.toInteger();
final Integer task = TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (count.intValue() >= requiredChanges) {
TaskManager.runTaskLater(whenDone, 1);
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
return;
}
if (chunks.size() == 0) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
return;
}
final Chunk chunk = chunks.iterator().next();
int bx = Math.max(chunk.getX() >> 4, bot.getX());
int bz = Math.max(chunk.getZ() >> 4, bot.getZ());
int ex = Math.max((chunk.getX() >> 4) + 15, top.getX());
int ez = Math.max((chunk.getZ() >> 4) + 15, top.getZ());
// count changes
count.add(checkModified(plot.world, bx, ex, 1, cpw.PLOT_HEIGHT - 1, bz, ez, cpw.MAIN_BLOCK));
count.add(checkModified(plot.world, bx, ex, cpw.PLOT_HEIGHT, cpw.PLOT_HEIGHT, bz, ez, cpw.TOP_BLOCK));
}
}, 1);
TaskManager.tasks.put(currentIndex, task);
}
@Override
public int checkModified(final int threshhold, final String worldname, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks) {
public int checkModified(final String worldname, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks) {
final World world = BukkitUtil.getWorld(worldname);
int count = 0;
for (int y = y1; y <= y2; y++) {
@ -37,9 +108,6 @@ public class BukkitHybridUtils extends HybridUtils {
}
if (!same) {
count++;
if (count > threshhold) {
return -1;
}
}
}
}

View File

@ -16,41 +16,14 @@ import com.intellectualcrafters.plot.util.BlockManager;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
public abstract class HybridUtils {
public static HybridUtils manager;
public abstract void checkModified(Plot plot, int requiredChanges, Runnable ifPassed);
public boolean checkModified(final Plot plot, int requiredChanges) {
final Location bottom = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1);
final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id);
final int botx = bottom.getX();
final int botz = bottom.getZ();
final int topx = top.getX();
final int topz = top.getZ();
final HybridPlotWorld hpw = (HybridPlotWorld) PlotSquared.getPlotWorld(plot.world);
final PlotBlock[] air = new PlotBlock[] { new PlotBlock((short) 0, (byte) 0) };
int changes = checkModified(requiredChanges, plot.world, botx, topx, hpw.PLOT_HEIGHT, hpw.PLOT_HEIGHT, botz, topz, hpw.TOP_BLOCK);
if (changes == -1) {
return true;
}
requiredChanges -= changes;
changes = checkModified(requiredChanges, plot.world, botx, topx, hpw.PLOT_HEIGHT + 1, hpw.PLOT_HEIGHT + 1, botz, topz, air);
if (changes == -1) {
return true;
}
requiredChanges -= changes;
changes = checkModified(requiredChanges, plot.world, botx, topx, hpw.PLOT_HEIGHT + 2, BukkitUtil.getMaxHeight(plot.world) - 1, botz, topz, air);
if (changes == -1) {
return true;
}
requiredChanges -= changes;
changes = checkModified(requiredChanges, plot.world, botx, topx, 1, hpw.PLOT_HEIGHT - 1, botz, topz, hpw.MAIN_BLOCK);
return changes == -1;
}
public abstract int checkModified(final int threshhold, final String world, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks);
public abstract int checkModified(final String world, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks);
public boolean setupRoadSchematic(final Plot plot) {
final String world = plot.world;

View File

@ -1,11 +1,17 @@
package com.intellectualcrafters.plot.util;
import java.util.HashMap;
import java.util.HashSet;
import org.apache.commons.lang.mutable.MutableInt;
import com.intellectualcrafters.plot.PlotSquared;
public abstract class TaskManager {
public static HashSet<String> TELEPORT_QUEUE = new HashSet<>();
public static MutableInt index = new MutableInt(0);
public static HashMap<Integer, Integer> tasks = new HashMap<>();
public abstract int taskRepeat(final Runnable r, int interval);

View File

@ -59,9 +59,6 @@ import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.TaskManager;
public class BukkitChunkManager extends ChunkManager {
public static MutableInt index = new MutableInt(0);
public static HashMap<Integer, Integer> tasks = new HashMap<>();
@Override
public ArrayList<ChunkLoc> getChunkChunks(final String world) {
final String directory = Bukkit.getWorldContainer() + File.separator + world + File.separator + "region";
@ -152,7 +149,7 @@ public class BukkitChunkManager extends ChunkManager {
*/
@Override
public boolean copyRegion(final Location pos1, final Location pos2, final Location newPos, final Runnable whenDone) {
index.increment();
TaskManager.index.increment();
final int relX = newPos.getX() - pos1.getX();
final int relZ = newPos.getZ() - pos1.getZ();
@ -183,19 +180,19 @@ public class BukkitChunkManager extends ChunkManager {
}
}
final Plugin plugin = BukkitMain.THIS;
final Integer currentIndex = index.toInteger();
final Integer currentIndex = TaskManager.index.toInteger();
final int loadTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
final long start = System.currentTimeMillis();
while ((System.currentTimeMillis() - start) < 25) {
if (toGenerate.size() == 0) {
Bukkit.getScheduler().cancelTask(tasks.get(currentIndex));
tasks.remove(currentIndex);
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
TaskManager.runTask(new Runnable() {
@Override
public void run() {
index.increment();
TaskManager.index.increment();
// Copy entities
initMaps();
for (int x = c1x; x <= c2x; x++) {
@ -209,7 +206,7 @@ public class BukkitChunkManager extends ChunkManager {
restoreEntities(newWorld, relX, relZ);
// Copy blocks
final MutableInt mx = new MutableInt(sx);
final Integer currentIndex = index.toInteger();
final Integer currentIndex = TaskManager.index.toInteger();
final int maxY = oldWorld.getMaxHeight();
final Integer task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
@ -234,14 +231,14 @@ public class BukkitChunkManager extends ChunkManager {
chunk.unload(true, true);
}
TaskManager.runTask(whenDone);
Bukkit.getScheduler().cancelTask(tasks.get(currentIndex));
tasks.remove(currentIndex);
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
return;
}
}
};
}, 1, 1);
tasks.put(currentIndex, task);
TaskManager.tasks.put(currentIndex, task);
}
});
return;
@ -253,13 +250,13 @@ public class BukkitChunkManager extends ChunkManager {
}
}
}, 1l, 1l);
tasks.put(currentIndex, loadTask);
TaskManager.tasks.put(currentIndex, loadTask);
return true;
}
@Override
public boolean regenerateRegion(final Location pos1, final Location pos2, final Runnable whenDone) {
index.increment();
TaskManager.index.increment();
final Plugin plugin = BukkitMain.THIS;
final World world = Bukkit.getWorld(pos1.getWorld());
final Chunk c1 = world.getChunkAt(pos1.getX() >> 4, pos1.getZ() >> 4);
@ -282,14 +279,14 @@ public class BukkitChunkManager extends ChunkManager {
}
}
final int maxY = world.getMaxHeight();
final Integer currentIndex = index.toInteger();
final Integer currentIndex = TaskManager.index.toInteger();
final Integer task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
if (chunks.size() == 0) {
TaskManager.runTaskLater(whenDone, 1);
Bukkit.getScheduler().cancelTask(tasks.get(currentIndex));
tasks.remove(currentIndex);
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
return;
}
CURRENT_PLOT_CLEAR = new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
@ -346,7 +343,7 @@ public class BukkitChunkManager extends ChunkManager {
CURRENT_PLOT_CLEAR = null;
}
}, 1, 1);
tasks.put(currentIndex, task);
TaskManager.tasks.put(currentIndex, task);
return true;
}