Fix hash code problem with zoomed-out tiles - caused incomplete

updates
This commit is contained in:
Mike Primm 2011-06-24 11:44:21 -05:00
parent 214fec208d
commit 5bb3249dfe

View File

@ -35,14 +35,16 @@ public class DynmapWorld {
private int extrazoomoutlevels; /* Number of additional zoom out levels to generate */ private int extrazoomoutlevels; /* Number of additional zoom out levels to generate */
public File worldtilepath; public File worldtilepath;
private Object lock = new Object(); private Object lock = new Object();
private HashSet<File> zoomoutupdates[]; private HashSet<String> zoomoutupdates[];
private boolean checkts = true; /* Check timestamps on first run with new configuration */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void setExtraZoomOutLevels(int lvl) { public void setExtraZoomOutLevels(int lvl) {
extrazoomoutlevels = lvl; extrazoomoutlevels = lvl;
zoomoutupdates = new HashSet[lvl]; zoomoutupdates = new HashSet[lvl];
for(int i = 0; i < lvl; i++) for(int i = 0; i < lvl; i++)
zoomoutupdates[i] = new HashSet<File>(); zoomoutupdates[i] = new HashSet<String>();
checkts = true;
} }
public int getExtraZoomOutLevels() { return extrazoomoutlevels; } public int getExtraZoomOutLevels() { return extrazoomoutlevels; }
@ -54,7 +56,7 @@ public class DynmapWorld {
if(level >= extrazoomoutlevels) if(level >= extrazoomoutlevels)
return; return;
synchronized(lock) { synchronized(lock) {
zoomoutupdates[level].add(f); zoomoutupdates[level].add(f.getPath());
} }
} }
@ -62,7 +64,7 @@ public class DynmapWorld {
if(level >= extrazoomoutlevels) if(level >= extrazoomoutlevels)
return false; return false;
synchronized(lock) { synchronized(lock) {
return zoomoutupdates[level].remove(f); return zoomoutupdates[level].remove(f.getPath());
} }
} }
@ -92,6 +94,7 @@ public class DynmapWorld {
for(int i = 0; i < extrazoomoutlevels; i++) { for(int i = 0; i < extrazoomoutlevels; i++) {
freshenZoomOutFilesByLevel(i); freshenZoomOutFilesByLevel(i);
} }
checkts = false; /* Just handle queued updates after first scan */
} }
private static class PrefixData { private static class PrefixData {
@ -105,10 +108,6 @@ public class DynmapWorld {
String zfnprefix; String zfnprefix;
} }
/**
* File based scan - used for priming map after server startup
* @param zoomlevel
*/
public void freshenZoomOutFilesByLevel(int zoomlevel) { public void freshenZoomOutFilesByLevel(int zoomlevel) {
int cnt = 0; int cnt = 0;
Debug.debug("freshenZoomOutFiles(" + world.getName() + "," + zoomlevel + ")"); Debug.debug("freshenZoomOutFiles(" + world.getName() + "," + zoomlevel + ")");
@ -211,7 +210,7 @@ public class DynmapWorld {
int cnt = 0; int cnt = 0;
/* Do processing */ /* Do processing */
for(ProcessTileRec s : toprocess.values()) { for(ProcessTileRec s : toprocess.values()) {
processZoomTile(pd, dir, s.zf, s.zfname, s.x - (pd.neg_step_x?step:0), s.y); processZoomTile(pd, dir, s.zf, s.zfname, s.x, s.y);
cnt++; cnt++;
} }
Debug.debug("processZoomDirectory(" + dir.getPath() + "," + pd.baseprefix + ") - done (" + cnt + " files)"); Debug.debug("processZoomDirectory(" + dir.getPath() + "," + pd.baseprefix + ") - done (" + cnt + " files)");
@ -219,6 +218,11 @@ public class DynmapWorld {
} }
private ProcessTileRec processZoomFile(File f, PrefixData pd) { private ProcessTileRec processZoomFile(File f, PrefixData pd) {
/* If not checking timstamp, we're out if nothing queued for this file */
if(!checkts) {
if(!popQueuedUpdate(f, pd.zoomlevel))
return null;
}
int step = pd.stepsize << pd.zoomlevel; int step = pd.stepsize << pd.zoomlevel;
String fn = f.getName(); String fn = f.getName();
/* Parse filename to predict zoomed out file */ /* Parse filename to predict zoomed out file */
@ -250,9 +254,11 @@ public class DynmapWorld {
/* Make name of corresponding zoomed tile */ /* Make name of corresponding zoomed tile */
String zfname = makeFilePath(pd, x, y, true); String zfname = makeFilePath(pd, x, y, true);
File zf = new File(worldtilepath, zfname); File zf = new File(worldtilepath, zfname);
/* If we're not updated, and zoom file exists and is older than our file, nothing to do */ if(checkts) { /* If checking timestamp, see if we need update based on enqueued update OR old file time */
if((!popQueuedUpdate(f, pd.zoomlevel)) && zf.exists() && (zf.lastModified() >= f.lastModified())) { /* If we're not updated, and zoom file exists and is older than our file, nothing to do */
return null; if((!popQueuedUpdate(f, pd.zoomlevel)) && zf.exists() && (zf.lastModified() >= f.lastModified())) {
return null;
}
} }
ProcessTileRec rec = new ProcessTileRec(); ProcessTileRec rec = new ProcessTileRec();
rec.zf = zf; rec.zf = zf;
@ -269,6 +275,8 @@ public class DynmapWorld {
KzedBufferedImage kzIm = null; KzedBufferedImage kzIm = null;
int[] argb = new int[width*height]; int[] argb = new int[width*height];
int step = pd.stepsize << pd.zoomlevel; int step = pd.stepsize << pd.zoomlevel;
int ztx = tx;
tx = tx - (pd.neg_step_x?step:0); /* Adjust for negative step */
/* create image buffer */ /* create image buffer */
kzIm = KzedMap.allocateBufferedImage(width, height); kzIm = KzedMap.allocateBufferedImage(width, height);
@ -279,6 +287,7 @@ public class DynmapWorld {
if(f.exists()) { if(f.exists()) {
BufferedImage im = null; BufferedImage im = null;
FileLockManager.getReadLock(f); FileLockManager.getReadLock(f);
popQueuedUpdate(f, pd.zoomlevel);
try { try {
im = ImageIO.read(f); im = ImageIO.read(f);
} catch (IOException e) { } catch (IOException e) {
@ -316,10 +325,10 @@ public class DynmapWorld {
} }
FileLockManager.getWriteLock(zf); FileLockManager.getWriteLock(zf);
TileHashManager hashman = MapManager.mapman.hashman; TileHashManager hashman = MapManager.mapman.hashman;
long crc = hashman.calculateTileHash(argb); /* Get hash of tile */ long crc = hashman.calculateTileHash(kzIm.argb_buf); /* Get hash of tile */
int tilex = tx/step/2; int tilex = ztx/step/2;
int tiley = ty/step/2; int tiley = ty/step/2;
String key = world.getName()+"."+pd.zoomprefix+pd.baseprefix; String key = world.getName()+".z"+pd.zoomprefix+pd.baseprefix;
if((!zf.exists()) || (crc != MapManager.mapman.hashman.getImageHashCode(key, null, tilex, tiley))) { if((!zf.exists()) || (crc != MapManager.mapman.hashman.getImageHashCode(key, null, tilex, tiley))) {
try { try {
if(!zf.getParentFile().exists()) if(!zf.getParentFile().exists())
@ -335,9 +344,6 @@ public class DynmapWorld {
MapManager.mapman.pushUpdate(this.world, new Client.Tile(zfname)); MapManager.mapman.pushUpdate(this.world, new Client.Tile(zfname));
enqueueZoomOutUpdate(zf, pd.zoomlevel+1); enqueueZoomOutUpdate(zf, pd.zoomlevel+1);
} }
else {
zf.setLastModified(System.currentTimeMillis()); /* Touch the existing file */
}
FileLockManager.releaseWriteLock(zf); FileLockManager.releaseWriteLock(zf);
KzedMap.freeBufferedImage(kzIm); KzedMap.freeBufferedImage(kzIm);
} }