From 87ed332a56212b1df852874333207110d319d0aa Mon Sep 17 00:00:00 2001 From: Arndt Brenschede Date: Sun, 2 Feb 2014 20:37:22 +0100 Subject: [PATCH] added more cache reuse for better short-route performance --- .../java/btools/mapaccess/MicroCache.java | 48 ++++++++++++++-- .../java/btools/mapaccess/NodesCache.java | 57 ++++++++++++++++++- .../main/java/btools/mapaccess/OsmFile.java | 41 ++++++++++++- 3 files changed, 138 insertions(+), 8 deletions(-) diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/MicroCache.java b/brouter-mapaccess/src/main/java/btools/mapaccess/MicroCache.java index efbbcd9..eb9911d 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/MicroCache.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/MicroCache.java @@ -24,6 +24,11 @@ final class MicroCache private int aboffset; private int ablength; + // cache control: a virgin cache can be + // put to ghost state for later recovery + boolean virgin = true; + boolean ghost = false; + public MicroCache( OsmFile segfile, int lonIdx80, int latIdx80, byte[] iobuffer ) throws Exception { int lonDegree = lonIdx80/80; @@ -40,6 +45,7 @@ final class MicroCache if ( asize == 0 ) { + ab = null; return; } if ( asize > iobuffer.length ) @@ -105,9 +111,19 @@ final class MicroCache return size; } + public int getDataSize() + { + return ab == null ? 0 : ab.length; + } + /** - * @return the value for "id", - * Throw an exception if not contained in the map. + * Set the internal reader (aboffset, ablength) + * to the body data for the given id + * + * @return true if id was found + * + * Throws an exception if that id was already requested + * as an early detector for identity problems */ private boolean getAndClear( long id ) { @@ -148,7 +164,10 @@ final class MicroCache return false; } - public void fillNode( OsmNode node, OsmNodesMap nodesMap, DistanceChecker dc ) + /** + * Fill a hollow node with it's body data + */ + public void fillNode( OsmNode node, OsmNodesMap nodesMap, DistanceChecker dc, boolean doCollect ) { long id = node.getIdFromPos(); if ( getAndClear( id ) ) @@ -156,8 +175,18 @@ final class MicroCache node.parseNodeBody( this, ablength, nodesMap, dc ); } - if ( delcount > size / 2 ) // garbage collection + if ( doCollect && delcount > size / 2 ) // garbage collection { + collect(); + } + } + + void collect() + { + if ( delcount > 0 ) + { + virgin = false; + int nsize = size - delcount; if ( nsize == 0 ) { @@ -197,6 +226,17 @@ final class MicroCache } } + void unGhost() + { + ghost = false; + delcount = 0; + delbytes = 0; + for( int i=0; i getPositions( OsmNodesMap nodesMap ) { ArrayList positions = new ArrayList(); diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java index aed57f6..759af78 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java @@ -19,13 +19,16 @@ public final class NodesCache private HashMap fileCache; private byte[] iobuffer; - private OsmFile[][] fileRows = new OsmFile[180][]; + private OsmFile[][] fileRows; private ArrayList segmentList = new ArrayList(); public DistanceChecker distanceChecker; public boolean oom_carsubset_hint = false; + private long cacheSum = 0; + private boolean garbageCollectionEnabled = false; + public NodesCache( String segmentDir, OsmNodesMap nodesMap, int lookupVersion, boolean carMode, NodesCache oldCache ) { this.segmentDir = segmentDir; @@ -38,14 +41,55 @@ public final class NodesCache fileCache = oldCache.fileCache; iobuffer = oldCache.iobuffer; oom_carsubset_hint = oldCache.oom_carsubset_hint; + + // re-use old, virgin caches + fileRows = oldCache.fileRows; + for( OsmFile[] fileRow : fileRows ) + { + if ( fileRow == null ) continue; + for( OsmFile osmf : fileRow ) + { + cacheSum += osmf.setGhostState(); + } + } } else { fileCache = new HashMap(4); + fileRows = new OsmFile[180][]; iobuffer = new byte[65636]; } } + // if the cache sum exceeded a threshold, + // clean all ghosts and enable garbage collection + private void checkEnableCacheCleaning() + { + if ( cacheSum < 200000 || garbageCollectionEnabled ) return; + + for( int i=0; i