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.File;
import java.io.IOException; import java.io.IOException;
import java.sql.Blob;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;

View File

@ -1,8 +1,11 @@
package com.intellectualcrafters.plot.generator; package com.intellectualcrafters.plot.generator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import org.apache.commons.lang.mutable.MutableInt;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
@ -13,14 +16,82 @@ import com.intellectualcrafters.plot.BukkitMain;
import com.intellectualcrafters.plot.PlotSquared; import com.intellectualcrafters.plot.PlotSquared;
import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.object.ChunkLoc; 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.PlotBlock;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.ChunkManager; 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; import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
public class BukkitHybridUtils extends HybridUtils { 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 @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 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 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); final World world = BukkitUtil.getWorld(worldname);
int count = 0; int count = 0;
for (int y = y1; y <= y2; y++) { for (int y = y1; y <= y2; y++) {
@ -37,9 +108,6 @@ public class BukkitHybridUtils extends HybridUtils {
} }
if (!same) { if (!same) {
count++; 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.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.SchematicHandler; import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
public abstract class HybridUtils { public abstract class HybridUtils {
public static HybridUtils manager; public static HybridUtils manager;
public boolean checkModified(final Plot plot, int requiredChanges) { public abstract void checkModified(Plot plot, int requiredChanges, Runnable ifPassed);
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) { public boolean setupRoadSchematic(final Plot plot) {
final String world = plot.world; final String world = plot.world;

View File

@ -1,12 +1,18 @@
package com.intellectualcrafters.plot.util; package com.intellectualcrafters.plot.util;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang.mutable.MutableInt;
import com.intellectualcrafters.plot.PlotSquared; import com.intellectualcrafters.plot.PlotSquared;
public abstract class TaskManager { public abstract class TaskManager {
public static HashSet<String> TELEPORT_QUEUE = new HashSet<>(); 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); public abstract int taskRepeat(final Runnable r, int interval);
public abstract void taskAsync(final Runnable r); public abstract void taskAsync(final Runnable r);

View File

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