From 530eb0ae9e3606b486c9f5781d0a4cf19f0054ea Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Tue, 10 Jan 2012 12:34:08 +0800 Subject: [PATCH] Shift most of touch processing off server main thread --- src/main/java/org/dynmap/DynmapLocation.java | 4 +- src/main/java/org/dynmap/DynmapPlugin.java | 149 ++++++------ src/main/java/org/dynmap/MapManager.java | 215 +++++++++++++----- .../java/org/dynmap/utils/SnapshotCache.java | 16 -- 4 files changed, 232 insertions(+), 152 deletions(-) diff --git a/src/main/java/org/dynmap/DynmapLocation.java b/src/main/java/org/dynmap/DynmapLocation.java index c51e6308..89f41e8c 100644 --- a/src/main/java/org/dynmap/DynmapLocation.java +++ b/src/main/java/org/dynmap/DynmapLocation.java @@ -4,12 +4,12 @@ package org.dynmap; * Generic block location */ public class DynmapLocation { - public int x, y, z; + public double x, y, z; public String world; public DynmapLocation() {} - public DynmapLocation(String w, int x, int y, int z) { + public DynmapLocation(String w, double x, double y, double z) { world = w; this.x = x; this.y = y; this.z = z; } diff --git a/src/main/java/org/dynmap/DynmapPlugin.java b/src/main/java/org/dynmap/DynmapPlugin.java index b5e6a451..41ba81fc 100644 --- a/src/main/java/org/dynmap/DynmapPlugin.java +++ b/src/main/java/org/dynmap/DynmapPlugin.java @@ -25,7 +25,6 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.CustomEventListener; @@ -111,7 +110,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { /* Flag to let code know that we're doing reload - make sure we don't double-register event handlers */ public boolean is_reload = false; - private boolean generate_only = false; private static boolean ignore_chunk_loads = false; /* Flag keep us from processing our own chunk loads */ private HashMap> event_handlers = new HashMap>(); @@ -130,7 +128,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { } /* Add/Replace branches in configuration tree with contribution from a separate file */ - @SuppressWarnings("unchecked") private void mergeConfigurationBranch(ConfigurationNode cfgnode, String branch, boolean replace_existing, boolean islist) { Object srcbranch = cfgnode.getObject(branch); if(srcbranch == null) @@ -521,10 +518,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockPlace(BlockPlaceEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onplace) { - mapManager.touch(dloc, "blockplace"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockplace"); } } @@ -532,10 +530,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockBreak(BlockBreakEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onbreak) { - mapManager.touch(dloc, "blockbreak"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockbreak"); } } @@ -543,10 +542,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onLeavesDecay(LeavesDecayEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onleaves) { - mapManager.touch(dloc, "leavesdecay"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "leavesdecay"); } } @@ -554,10 +554,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockBurn(BlockBurnEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onburn) { - mapManager.touch(dloc, "blockburn"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockburn"); } } @@ -565,10 +566,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockForm(BlockFormEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onblockform) { - mapManager.touch(dloc, "blockform"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockform"); } } @@ -576,10 +578,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockFade(BlockFadeEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onblockfade) { - mapManager.touch(dloc, "blockfade"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfade"); } } @@ -587,10 +590,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockSpread(BlockSpreadEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onblockspread) { - mapManager.touch(dloc, "blockspread"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockspread"); } } @@ -598,24 +602,27 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public void onBlockFromTo(BlockFromToEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getToBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getToBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onblockfromto) - mapManager.touch(dloc, "blockfromto"); - dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfromto"); + loc = event.getBlock().getLocation(); + wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onblockfromto) - mapManager.touch(dloc, "blockfromto"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfromto"); } @Override public void onBlockPhysics(BlockPhysicsEvent event) { if(event.isCancelled()) return; - DynmapLocation dloc = toLoc(event.getBlock().getLocation()); - mapManager.sscache.invalidateSnapshot(dloc); + Location loc = event.getBlock().getLocation(); + String wn = loc.getWorld().getName(); + mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); if(onblockphysics) { - mapManager.touch(dloc, "blockphysics"); + mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockphysics"); } } @@ -631,17 +638,18 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { } catch (ClassCastException ccx) { dir = BlockFace.NORTH; } - DynmapLocation dloc = toLoc(loc); - mapManager.sscache.invalidateSnapshot(dloc); + String wn = loc.getWorld().getName(); + int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ(); + mapManager.sscache.invalidateSnapshot(wn, x, y, z); if(onpiston) - mapManager.touch(dloc, "pistonretract"); + mapManager.touch(wn, x, y, z, "pistonretract"); for(int i = 0; i < 2; i++) { - dloc.x += dir.getModX(); - dloc.y += dir.getModY(); - dloc.z += dir.getModZ(); - mapManager.sscache.invalidateSnapshot(dloc); + x += dir.getModX(); + y += dir.getModY(); + z += dir.getModZ(); + mapManager.sscache.invalidateSnapshot(wn, x, y, z); if(onpiston) - mapManager.touch(dloc, "pistonretract"); + mapManager.touch(wn, x, y, z, "pistonretract"); } } @Override @@ -650,24 +658,24 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { return; Block b = event.getBlock(); Location loc = b.getLocation(); - DynmapLocation dloc = toLoc(loc); - mapManager.sscache.invalidateSnapshot(dloc); BlockFace dir; try { /* Workaround Bukkit bug = http://leaky.bukkit.org/issues/1227 */ dir = event.getDirection(); } catch (ClassCastException ccx) { dir = BlockFace.NORTH; } - mapManager.sscache.invalidateSnapshot(dloc); + String wn = loc.getWorld().getName(); + int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ(); + mapManager.sscache.invalidateSnapshot(wn, x, y, z); if(onpiston) - mapManager.touch(dloc, "pistonretract"); + mapManager.touch(wn, x, y, z, "pistonretract"); for(int i = 0; i < 1+event.getLength(); i++) { - dloc.x += dir.getModX(); - dloc.y += dir.getModY(); - dloc.z += dir.getModZ(); - mapManager.sscache.invalidateSnapshot(dloc); + x += dir.getModX(); + y += dir.getModY(); + z += dir.getModZ(); + mapManager.sscache.invalidateSnapshot(wn, x, y, z); if(onpiston) - mapManager.touch(dloc, "pistonretract"); + mapManager.touch(wn, x, y, z, "pistonretract"); } } }; @@ -707,22 +715,16 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { registerEvent(Event.Type.BLOCK_PISTON_RETRACT, blockTrigger); /* Register player event trigger handlers */ PlayerListener playerTrigger = new PlayerListener() { - private DynmapLocation dloc = new DynmapLocation(); - private DynmapLocation toLoc(Location loc) { - dloc.x = loc.getBlockX(); dloc.y = loc.getBlockY(); - dloc.z = loc.getBlockZ(); dloc.world = loc.getWorld().getName(); - return dloc; - } @Override public void onPlayerJoin(PlayerJoinEvent event) { - toLoc(event.getPlayer().getLocation()); - mapManager.touch(dloc, "playerjoin"); + Location loc = event.getPlayer().getLocation(); + mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "playerjoin"); } @Override public void onPlayerMove(PlayerMoveEvent event) { - toLoc(event.getPlayer().getLocation()); - mapManager.touch(dloc, "playermove"); + Location loc = event.getPlayer().getLocation(); + mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "playermove"); } }; @@ -769,7 +771,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { /* Register world event triggers */ WorldListener worldTrigger = new WorldListener() { - private DynmapLocation dloc = new DynmapLocation(); @Override public void onChunkLoad(ChunkLoadEvent event) { if(ignore_chunk_loads) @@ -921,10 +922,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { if (c.equals("render") && checkPlayerPermission(sender,"render")) { if (player != null) { - int invalidates = mapManager.touch(toLoc(player.getLocation()), "render"); - sender.sendMessage("Queued " + invalidates + " tiles" + (invalidates == 0 - ? " (world is not loaded?)" - : "...")); + Location loc = player.getLocation(); + + mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "render"); + + sender.sendMessage("Tile render queued."); } else { sender.sendMessage("Command can only be issued by player."); @@ -1026,7 +1028,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { w = mapManager.getWorld(wname); if(w != null) { DynmapLocation spawn = w.getSpawnLocation(); - DynmapLocation loc = new DynmapLocation(wname, w.configuration.getInteger("center/x", spawn.x), w.configuration.getInteger("center/y", spawn.y), w.configuration.getInteger("center/z", spawn.z)); + DynmapLocation loc = new DynmapLocation(wname, w.configuration.getDouble("center/x", spawn.x), w.configuration.getDouble("center/y", spawn.y), w.configuration.getDouble("center/z", spawn.z)); mapManager.renderFullWorld(loc,sender, map, false); } else @@ -1701,12 +1703,12 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { * * @param l0 - first location (required) * @param l1 - second location (if null, only single point invalidated (l0)) - * @return number of tiles queued to be rerendered + * @return zero or higher if request queued, -1 if error */ public int triggerRenderOfVolume(Location l0, Location l1) { if(mapManager != null) { if(l1 == null) - return mapManager.touch(l0.getWorld().getName(), l0.getBlockX(), l0.getBlockY(), l0.getBlockZ(), "api"); + mapManager.touch(l0.getWorld().getName(), l0.getBlockX(), l0.getBlockY(), l0.getBlockZ(), "api"); else { int minx = Math.min(l0.getBlockX(), l1.getBlockX()); int maxx = Math.max(l0.getBlockX(), l1.getBlockX()); @@ -1715,7 +1717,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { int minz = Math.min(l0.getBlockZ(), l1.getBlockZ()); int maxz = Math.max(l0.getBlockZ(), l1.getBlockZ()); - return mapManager.touchVolume(l0.getWorld().getName(), minx, miny, minz, maxx, maxy, maxz, "api"); + mapManager.touchVolume(l0.getWorld().getName(), minx, miny, minz, maxx, maxy, maxz, "api"); } } return 0; @@ -1886,18 +1888,17 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { @Override public int triggerRenderOfBlock(String wid, int x, int y, int z) { if(mapManager != null) - return mapManager.touch(wid, x, y, z, "api"); - else - return 0; + mapManager.touch(wid, x, y, z, "api"); + return 0; } @Override public int triggerRenderOfVolume(String wid, int minx, int miny, int minz, int maxx, int maxy, int maxz) { if(mapManager != null) { if((minx == maxx) && (miny == maxy) && (minz == maxz)) - return mapManager.touch(wid, minx, miny, minz, "api"); + mapManager.touch(wid, minx, miny, minz, "api"); else - return mapManager.touchVolume(wid, minx, miny, minz, maxx, maxy, maxz, "api"); + mapManager.touchVolume(wid, minx, miny, minz, maxx, maxy, maxz, "api"); } return 0; } diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java index 20f8603b..26b0a8c9 100644 --- a/src/main/java/org/dynmap/MapManager.java +++ b/src/main/java/org/dynmap/MapManager.java @@ -86,6 +86,32 @@ public class MapManager { private DynmapScheduledThreadPoolExecutor render_pool; private static final int POOL_SIZE = 3; + /* Touch event queues */ + private static class TouchEvent implements Comparable { + int x, y, z; + String world; + String reason; + @Override + public int compareTo(TouchEvent te) { + if(x < te.x) return -1; + if(x > te.x) return 1; + if(y < te.y) return -1; + if(y > te.y) return 1; + if(z < te.z) return -1; + if(z > te.z) return 1; + return world.compareTo(te.world); + } + } + private static class TouchVolumeEvent { + int xmin, ymin, zmin; + int xmax, ymax, zmax; + String world; + String reason; + } + private TreeSet touch_events = new TreeSet(); + private LinkedList touch_volume_events = new LinkedList(); + private Object touch_lock = new Object(); + private HashMap mapstats = new HashMap(); private static class MapStats { @@ -94,9 +120,10 @@ public class MapManager { int updatedcnt; int transparentcnt; } - + /* synchronized using 'lock' */ private HashMap trigstats = new HashMap(); + private static class TriggerStats { long callsmade; long callswithtiles; @@ -235,10 +262,10 @@ public class MapManager { rendertype = RENDERTYPE_FULLRENDER; } else { - cxmin = (l.x - radius)>>4; - czmin = (l.z - radius)>>4; - cxmax = (l.x + radius+15)>>4; - czmax = (l.z + radius+15)>>4; + cxmin = ((int)l.x - radius)>>4; + czmin = ((int)l.z - radius)>>4; + cxmax = ((int)l.x + radius + 15)>>4; + czmax = ((int)l.z + radius + 15)>>4; rendertype = RENDERTYPE_RADIUSRENDER; } this.mapname = mapname; @@ -453,7 +480,7 @@ public class MapManager { renderedmaps.addAll(map.getMapsSharingRender(world)); /* Now, prime the render queue */ - for (MapTile mt : map.getTiles(world, loc.x, loc.y, loc.z)) { + for (MapTile mt : map.getTiles(world, (int)loc.x, (int)loc.y, (int)loc.z)) { if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) { found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true); renderQueue.add(mt); @@ -462,7 +489,7 @@ public class MapManager { if(!updaterender) { /* Only add other seed points for fullrender */ /* Add spawn location too (helps with some worlds where 0,64,0 may not be generated */ DynmapLocation sloc = world.getSpawnLocation(); - for (MapTile mt : map.getTiles(world, sloc.x, sloc.y, sloc.z)) { + for (MapTile mt : map.getTiles(world, (int)sloc.x, (int)sloc.y, (int)sloc.z)) { if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) { found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true); renderQueue.add(mt); @@ -470,7 +497,7 @@ public class MapManager { } if(world.seedloc != null) { for(DynmapLocation seed : world.seedloc) { - for (MapTile mt : map.getTiles(world, seed.x, seed.y, seed.z)) { + for (MapTile mt : map.getTiles(world, (int)seed.x, (int)seed.y, (int)seed.z)) { if (!found.getFlag(mt.tileOrdinalX(),mt.tileOrdinalY())) { found.setFlag(mt.tileOrdinalX(),mt.tileOrdinalY(), true); renderQueue.add(mt); @@ -688,6 +715,13 @@ public class MapManager { } } + private class DoTouchProcessing implements Runnable { + public void run() { + processTouchEvents(); + scheduleDelayedJob(this, 1000); /* Once per second */ + } + } + public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) { plug_in = plugin; mapman = this; @@ -1010,62 +1044,31 @@ public class MapManager { } } - public int touch(DynmapLocation l, String reason) { - return touch(l.world, l.x, l.y, l.z, reason); - } - - public int touch(String wname, int x, int y, int z, String reason) { - DynmapWorld world = getWorld(wname); - if (world == null) - return 0; - int invalidates = 0; - for (int i = 0; i < world.maps.size(); i++) { - MapTile[] tiles = world.maps.get(i).getTiles(world, x, y, z); - for (int j = 0; j < tiles.length; j++) { - if(invalidateTile(tiles[j])) - invalidates++; - } + public void touch(String wname, int x, int y, int z, String reason) { + TouchEvent evt = new TouchEvent(); + evt.world = wname; + evt.x = x; + evt.y = y; + evt.z = z; + evt.reason = reason; + synchronized(touch_lock) { + touch_events.add(evt); } - if(reason != null) { - TriggerStats ts = trigstats.get(reason); - if(ts == null) { - ts = new TriggerStats(); - trigstats.put(reason, ts); - } - ts.callsmade++; - if(invalidates > 0) { - ts.callswithtiles++; - ts.tilesqueued += invalidates; - } - } - return invalidates; } - public int touchVolume(String wname, int minx, int miny, int minz, int maxx, int maxy, int maxz, String reason) { - DynmapWorld world = getWorld(wname); - if (world == null) - return 0; - int invalidates = 0; - for (int i = 0; i < world.maps.size(); i++) { - MapTile[] tiles = world.maps.get(i).getTiles(world, minx, miny, minz, maxx, maxy, maxz); - for (int j = 0; j < tiles.length; j++) { - if(invalidateTile(tiles[j])) - invalidates++; - } + public void touchVolume(String wname, int minx, int miny, int minz, int maxx, int maxy, int maxz, String reason) { + TouchVolumeEvent evt = new TouchVolumeEvent(); + evt.world = wname; + evt.xmin = minx; + evt.xmax = maxx; + evt.ymin = miny; + evt.ymax = maxy; + evt.zmin = minz; + evt.zmax = maxz; + evt.reason = reason; + synchronized(touch_lock) { + touch_volume_events.add(evt); } - if(reason != null) { - TriggerStats ts = trigstats.get(reason); - if(ts == null) { - ts = new TriggerStats(); - trigstats.put(reason, ts); - } - ts.callsmade++; - if(invalidates > 0) { - ts.callswithtiles++; - ts.tilesqueued += invalidates; - } - } - return invalidates; } public boolean invalidateTile(MapTile tile) { @@ -1089,6 +1092,7 @@ public class MapManager { tileQueue.start(); scheduleDelayedJob(new DoZoomOutProcessing(), 60000); scheduleDelayedJob(new CheckWorldTimes(), 5000); + scheduleDelayedJob(new DoTouchProcessing(), 1000); /* Resume pending jobs */ for(FullWorldRenderState job : active_renders.values()) { scheduleDelayedJob(job, 5000); @@ -1401,4 +1405,95 @@ public class MapManager { } } } + + /** + * Process touch events + */ + private void processTouchEvents() { + TreeSet te = null; + LinkedList tve = null; + synchronized(touch_lock) { + if(touch_events.isEmpty() == false) { + te = touch_events; + touch_events = new TreeSet(); + } + if(touch_volume_events.isEmpty() == false) { + tve = touch_volume_events; + touch_volume_events = new LinkedList(); + } + } + DynmapWorld world = null; + String wname = ""; + + /* If any touch events, process them */ + if(te != null) { + for(TouchEvent evt : te) { + int invalidates = 0; + /* If different world, look it up */ + if(evt.world.equals(wname) == false) { + wname = evt.world; + world = getWorld(wname); + } + if(world == null) continue; + for (int i = 0; i < world.maps.size(); i++) { + MapTile[] tiles = world.maps.get(i).getTiles(world, evt.x, evt.y, evt.z); + for (int j = 0; j < tiles.length; j++) { + if(invalidateTile(tiles[j])) + invalidates++; + } + } + if(evt.reason != null) { + synchronized(lock) { + TriggerStats ts = trigstats.get(evt.reason); + if(ts == null) { + ts = new TriggerStats(); + trigstats.put(evt.reason, ts); + } + ts.callsmade++; + if(invalidates > 0) { + ts.callswithtiles++; + ts.tilesqueued += invalidates; + } + } + } + } + te.clear(); /* Clean up set */ + } + + /* If any volume touches */ + if(tve != null) { + for(TouchVolumeEvent evt : tve) { + /* If different world, look it up */ + if(evt.world.equals(wname) == false) { + wname = evt.world; + world = getWorld(wname); + } + if(world == null) continue; + int invalidates = 0; + for (int i = 0; i < world.maps.size(); i++) { + MapTile[] tiles = world.maps.get(i).getTiles(world, evt.xmin, evt.ymin, evt.zmin, evt.xmax, evt.ymax, evt.zmax); + for (int j = 0; j < tiles.length; j++) { + if(invalidateTile(tiles[j])) + invalidates++; + } + } + if(evt.reason != null) { + synchronized(lock) { + TriggerStats ts = trigstats.get(evt.reason); + if(ts == null) { + ts = new TriggerStats(); + trigstats.put(evt.reason, ts); + } + ts.callsmade++; + if(invalidates > 0) { + ts.callswithtiles++; + ts.tilesqueued += invalidates; + } + } + } + } + /* Clean up */ + tve.clear(); + } + } } diff --git a/src/main/java/org/dynmap/utils/SnapshotCache.java b/src/main/java/org/dynmap/utils/SnapshotCache.java index 27ae97a7..50f928e2 100644 --- a/src/main/java/org/dynmap/utils/SnapshotCache.java +++ b/src/main/java/org/dynmap/utils/SnapshotCache.java @@ -8,7 +8,6 @@ import java.util.LinkedHashMap; import java.util.Map; import org.bukkit.ChunkSnapshot; -import org.dynmap.DynmapLocation; public class SnapshotCache { private CacheHashMap snapcache; @@ -49,24 +48,9 @@ public class SnapshotCache { snapcache = new CacheHashMap(max_size); refqueue = new ReferenceQueue(); } - private String getKey(DynmapLocation loc) { - return loc.world + ":" + (loc.x>>4) + ":" + (loc.z>>4); - } private String getKey(String w, int cx, int cz) { return w + ":" + cx + ":" + cz; } - /** - * Invalidate cached snapshot, if in cache - */ - public void invalidateSnapshot(DynmapLocation loc) { - String key = getKey(loc); - CacheRec rec = snapcache.remove(key); - if(rec != null) { - snapcache.reverselookup.remove(rec.ref); - rec.ref.clear(); - } - processRefQueue(); - } /** * Invalidate cached snapshot, if in cache */