/** * Efficient cache or osmnodes * * @author ab */ package btools.mapaccess; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public final class NodesCache { private File segmentDir; private File secondarySegmentsDir = null; private OsmNodesMap nodesMap; private int lookupVersion; private int lookupMinorVersion; private boolean readVarLength; private boolean carMode; private boolean forceSecondaryData; private String currentFileName; private HashMap fileCache; private byte[] iobuffer; 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, int minorVersion, boolean varLen, boolean carMode, boolean forceSecondaryData, NodesCache oldCache ) { this.segmentDir = new File( segmentDir ); this.nodesMap = nodesMap; this.lookupVersion = lookupVersion; this.lookupMinorVersion = minorVersion; this.readVarLength = varLen; this.carMode = carMode; this.forceSecondaryData = forceSecondaryData; if ( !this.segmentDir.isDirectory() ) throw new RuntimeException( "segment directory " + segmentDir + " does not exist" ); if ( oldCache != null ) { fileCache = oldCache.fileCache; iobuffer = oldCache.iobuffer; oom_carsubset_hint = oldCache.oom_carsubset_hint; secondarySegmentsDir = oldCache.secondarySegmentsDir; // 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]; secondarySegmentsDir = StorageConfigHelper.getSecondarySegmentDir( segmentDir ); } } private File getFileFromSegmentDir( String filename ) { if ( forceSecondaryData ) { return new File( secondarySegmentsDir, filename ); } File f = new File( segmentDir, filename ); if ( secondarySegmentsDir != null && !f.exists() ) { File f2 = new File( secondarySegmentsDir, filename ); if ( f2.exists() ) return f2; } return f; } // 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 getAllNodes() { List all = new ArrayList(); for( MicroCache segment : segmentList ) { List positions = segment.getPositions( nodesMap ); all.addAll( positions ); } return all; } public void close() { for( PhysicalFile f: fileCache.values() ) { try { if ( f != null ) f.ra.close(); } catch( IOException ioe ) { // ignore } } } }