mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-24 11:15:21 +01:00
Add more metrics to chunk loading (for testing)
This commit is contained in:
parent
eeffa4f98d
commit
926d2a3dbc
@ -955,7 +955,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
else {
|
else {
|
||||||
dsender = new BukkitCommandSender(sender);
|
dsender = new BukkitCommandSender(sender);
|
||||||
}
|
}
|
||||||
return core.processCommand(dsender, cmd.getName(), commandLabel, args);
|
boolean rslt = core.processCommand(dsender, cmd.getName(), commandLabel, args);
|
||||||
|
if (commandLabel.equals("dynmap") && (args.length > 0) && (args[0].equals("stats"))) {
|
||||||
|
NewMapChunkCache.dumpStats(sender);
|
||||||
|
}
|
||||||
|
return rslt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import java.util.Map;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.ChunkSnapshot;
|
import org.bukkit.ChunkSnapshot;
|
||||||
import org.dynmap.DynmapChunk;
|
import org.dynmap.DynmapChunk;
|
||||||
import org.dynmap.DynmapCore;
|
import org.dynmap.DynmapCore;
|
||||||
@ -804,9 +805,44 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum TimeStep {
|
||||||
|
loadChunk,
|
||||||
|
getChunkAt,
|
||||||
|
getChunkSnapshot,
|
||||||
|
getTileEntityData,
|
||||||
|
unloadChunkNoSave,
|
||||||
|
unloadChunkRequest,
|
||||||
|
isChunkLoaded,
|
||||||
|
isInUnloadQueue,
|
||||||
|
getEmptyChunkSnapshot,
|
||||||
|
getSnapshotCache,
|
||||||
|
putSnapshotCache,
|
||||||
|
loadLoop,
|
||||||
|
loadCalls
|
||||||
|
}
|
||||||
|
public static long[] timetot = new long[16];
|
||||||
|
public static long[] cnttot = new long[16];
|
||||||
|
public static long[] timestart = new long[16];
|
||||||
|
|
||||||
|
private static final void startTime(TimeStep idx) {
|
||||||
|
timestart[idx.ordinal()] = System.nanoTime();
|
||||||
|
}
|
||||||
|
private static final void stopTime(TimeStep idx) {
|
||||||
|
int ord = idx.ordinal();
|
||||||
|
timetot[ord] += System.nanoTime() - timestart[ord];
|
||||||
|
cnttot[ord]++;
|
||||||
|
}
|
||||||
|
public static void dumpStats(CommandSender sender) {
|
||||||
|
for (TimeStep ts : TimeStep.values()) {
|
||||||
|
sender.sendMessage(" " + ts + ": " + timetot[ts.ordinal()] + "ns, " + cnttot[ts.ordinal()] + " calls, " + (0.001 * timetot[ts.ordinal()] / cnttot[ts.ordinal()]) + "us/call" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int loadChunks(int max_to_load) {
|
public int loadChunks(int max_to_load) {
|
||||||
if(dw.isLoaded() == false)
|
if(dw.isLoaded() == false)
|
||||||
return 0;
|
return 0;
|
||||||
|
startTime(TimeStep.loadCalls);
|
||||||
|
|
||||||
long t0 = System.nanoTime();
|
long t0 = System.nanoTime();
|
||||||
Object queue = helper.getUnloadQueue(helper.getNMSWorld(w));
|
Object queue = helper.getUnloadQueue(helper.getNMSWorld(w));
|
||||||
|
|
||||||
@ -818,6 +854,8 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||||||
//boolean isnormral = w.getEnvironment() == Environment.NORMAL;
|
//boolean isnormral = w.getEnvironment() == Environment.NORMAL;
|
||||||
// Load the required chunks.
|
// Load the required chunks.
|
||||||
while((cnt < max_to_load) && iterator.hasNext()) {
|
while((cnt < max_to_load) && iterator.hasNext()) {
|
||||||
|
startTime(TimeStep.loadLoop);
|
||||||
|
|
||||||
DynmapChunk chunk = iterator.next();
|
DynmapChunk chunk = iterator.next();
|
||||||
boolean vis = true;
|
boolean vis = true;
|
||||||
if(visible_limits != null) {
|
if(visible_limits != null) {
|
||||||
@ -841,7 +879,10 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||||||
ChunkSnapshot ss = null;
|
ChunkSnapshot ss = null;
|
||||||
long inhabited_ticks = 0;
|
long inhabited_ticks = 0;
|
||||||
DynIntHashMap tileData = null;
|
DynIntHashMap tileData = null;
|
||||||
|
startTime(TimeStep.getSnapshotCache);
|
||||||
SnapshotRec ssr = DynmapPlugin.plugin.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
|
SnapshotRec ssr = DynmapPlugin.plugin.sscache.getSnapshot(dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
|
||||||
|
stopTime(TimeStep.getSnapshotCache);
|
||||||
|
|
||||||
if(ssr != null) {
|
if(ssr != null) {
|
||||||
ss = ssr.ss;
|
ss = ssr.ss;
|
||||||
inhabited_ticks = ssr.inhabitedTicks;
|
inhabited_ticks = ssr.inhabitedTicks;
|
||||||
@ -857,32 +898,47 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||||||
snaparray[idx] = ss;
|
snaparray[idx] = ss;
|
||||||
snaptile[idx] = ssr.tileData;
|
snaptile[idx] = ssr.tileData;
|
||||||
inhabitedTicks[idx] = inhabited_ticks;
|
inhabitedTicks[idx] = inhabited_ticks;
|
||||||
|
stopTime(TimeStep.loadLoop);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
chunks_attempted++;
|
chunks_attempted++;
|
||||||
|
startTime(TimeStep.isChunkLoaded);
|
||||||
boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
|
boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
|
||||||
|
stopTime(TimeStep.isChunkLoaded);
|
||||||
boolean didload = false;
|
boolean didload = false;
|
||||||
boolean isunloadpending = false;
|
boolean isunloadpending = false;
|
||||||
if (queue != null) {
|
if (queue != null) {
|
||||||
|
startTime(TimeStep.isInUnloadQueue);
|
||||||
isunloadpending = helper.isInUnloadQueue(queue, chunk.x, chunk.z);
|
isunloadpending = helper.isInUnloadQueue(queue, chunk.x, chunk.z);
|
||||||
|
stopTime(TimeStep.isInUnloadQueue);
|
||||||
}
|
}
|
||||||
if (isunloadpending) { /* Workaround: can't be pending if not loaded */
|
if (isunloadpending) { /* Workaround: can't be pending if not loaded */
|
||||||
wasLoaded = true;
|
wasLoaded = true;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
startTime(TimeStep.loadChunk);
|
||||||
try {
|
try {
|
||||||
didload = w.loadChunk(chunk.x, chunk.z, false);
|
didload = w.loadChunk(chunk.x, chunk.z, false);
|
||||||
|
} finally {
|
||||||
|
stopTime(TimeStep.loadChunk);
|
||||||
|
}
|
||||||
} catch (Throwable t) { /* Catch chunk error from Bukkit */
|
} catch (Throwable t) { /* Catch chunk error from Bukkit */
|
||||||
Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName());
|
Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName());
|
||||||
if(!wasLoaded) { /* If wasn't loaded, we loaded it if it now is */
|
if(!wasLoaded) { /* If wasn't loaded, we loaded it if it now is */
|
||||||
|
startTime(TimeStep.isChunkLoaded);
|
||||||
didload = w.isChunkLoaded(chunk.x, chunk.z);
|
didload = w.isChunkLoaded(chunk.x, chunk.z);
|
||||||
|
stopTime(TimeStep.isChunkLoaded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If it did load, make cache of it */
|
/* If it did load, make cache of it */
|
||||||
if(didload) {
|
if(didload) {
|
||||||
tileData = new DynIntHashMap();
|
tileData = new DynIntHashMap();
|
||||||
|
|
||||||
|
startTime(TimeStep.getChunkAt);
|
||||||
Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */
|
Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */
|
||||||
|
stopTime(TimeStep.getChunkAt);
|
||||||
|
|
||||||
/* Get inhabited ticks count */
|
/* Get inhabited ticks count */
|
||||||
inhabited_ticks = helper.getInhabitedTicks(c);
|
inhabited_ticks = helper.getInhabitedTicks(c);
|
||||||
if(!vis) {
|
if(!vis) {
|
||||||
@ -895,11 +951,14 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(blockdata || highesty) {
|
if(blockdata || highesty) {
|
||||||
|
startTime(TimeStep.getChunkSnapshot);
|
||||||
ss = c.getChunkSnapshot(highesty, biome, biomeraw);
|
ss = c.getChunkSnapshot(highesty, biome, biomeraw);
|
||||||
|
stopTime(TimeStep.getChunkSnapshot);
|
||||||
if(use_spout) {
|
if(use_spout) {
|
||||||
ss = checkSpoutData(c, ss);
|
ss = checkSpoutData(c, ss);
|
||||||
}
|
}
|
||||||
/* Get tile entity data */
|
/* Get tile entity data */
|
||||||
|
startTime(TimeStep.getTileEntityData);
|
||||||
List<Object> vals = new ArrayList<Object>();
|
List<Object> vals = new ArrayList<Object>();
|
||||||
Map<?,?> tileents = helper.getTileEntitiesForChunk(c);
|
Map<?,?> tileents = helper.getTileEntitiesForChunk(c);
|
||||||
for(Object t : tileents.values()) {
|
for(Object t : tileents.values()) {
|
||||||
@ -928,15 +987,21 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stopTime(TimeStep.getTileEntityData);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
startTime(TimeStep.getEmptyChunkSnapshot);
|
||||||
ss = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw);
|
ss = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw);
|
||||||
|
stopTime(TimeStep.getEmptyChunkSnapshot);
|
||||||
|
}
|
||||||
if(ss != null) {
|
if(ss != null) {
|
||||||
ssr = new SnapshotRec();
|
ssr = new SnapshotRec();
|
||||||
ssr.ss = ss;
|
ssr.ss = ss;
|
||||||
ssr.inhabitedTicks = inhabited_ticks;
|
ssr.inhabitedTicks = inhabited_ticks;
|
||||||
ssr.tileData = tileData;
|
ssr.tileData = tileData;
|
||||||
|
startTime(TimeStep.putSnapshotCache);
|
||||||
DynmapPlugin.plugin.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
|
DynmapPlugin.plugin.sscache.putSnapshot(dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
|
||||||
|
stopTime(TimeStep.putSnapshotCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int chunkIndex = (chunk.x-x_min) + (chunk.z - z_min)*x_dim;
|
int chunkIndex = (chunk.x-x_min) + (chunk.z - z_min)*x_dim;
|
||||||
@ -953,13 +1018,18 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||||||
* while the actual in-use chunk area for a player where the chunks are managed
|
* while the actual in-use chunk area for a player where the chunks are managed
|
||||||
* by the MC base server is 21x21 (or about a 160 block radius).
|
* by the MC base server is 21x21 (or about a 160 block radius).
|
||||||
* Also, if we did generate it, need to save it */
|
* Also, if we did generate it, need to save it */
|
||||||
|
startTime(TimeStep.unloadChunkNoSave);
|
||||||
helper.unloadChunkNoSave(w, c, chunk.x, chunk.z);
|
helper.unloadChunkNoSave(w, c, chunk.x, chunk.z);
|
||||||
|
stopTime(TimeStep.unloadChunkNoSave);
|
||||||
}
|
}
|
||||||
else if (isunloadpending) { /* Else, if loaded and unload is pending */
|
else if (isunloadpending) { /* Else, if loaded and unload is pending */
|
||||||
|
startTime(TimeStep.unloadChunkRequest);
|
||||||
w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */
|
w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */
|
||||||
|
stopTime(TimeStep.unloadChunkRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cnt++;
|
cnt++;
|
||||||
|
stopTime(TimeStep.loadLoop);
|
||||||
}
|
}
|
||||||
DynmapCore.setIgnoreChunkLoads(false);
|
DynmapCore.setIgnoreChunkLoads(false);
|
||||||
|
|
||||||
@ -974,6 +1044,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
total_loadtime += System.nanoTime() - t0;
|
total_loadtime += System.nanoTime() - t0;
|
||||||
|
stopTime(TimeStep.loadCalls);
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user