/** * cache for a single square * * @author ab */ package btools.mapaccess; import java.util.*; import java.io.*; import btools.util.Crc32; final class MicroCache { private long[] faid; private int[] fapos; private int size = 0; private int delcount = 0; private int delbytes = 0; private int p2size; // next power of 2 of size // the object parsing position and length private byte[] ab; 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; int latDegree = latIdx80/80; int lonIdxBase = (lonIdx80/5)*62500 + 31250; int latIdxBase = (latIdx80/5)*62500 + 31250; int subIdx = (latIdx80-80*latDegree)*80 + (lonIdx80-80*lonDegree); { ab = iobuffer; int asize = segfile.getDataInputForSubIdx(subIdx, ab); if ( asize == 0 ) { ab = null; return; } if ( asize > iobuffer.length ) { ab = new byte[asize]; asize = segfile.getDataInputForSubIdx(subIdx, ab); } aboffset = 0; size = readInt(); // get net size int nbytes = 0; for(int i = 0; i size ) p2size >>= 1; for(int i = 0; i 0 ) { int nn = n + offset; if ( nn < size && a[nn] <= id ) { n = nn; } offset >>= 1; } if ( a[n] == id ) { if ( ( fapos[n] & 0x80000000 ) == 0 ) { aboffset = fapos[n]; ablength = ( n+1 < size ? fapos[n+1] & 0x7fffffff : ab.length ) - aboffset; fapos[n] |= 0x80000000; // mark deleted delbytes+= ablength; delcount++; return true; } else { throw new RuntimeException( "MicroCache: node already consumed: id=" + id ); } } return false; } /** * 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 ) ) { node.parseNodeBody( this, ablength, nodesMap, dc ); } if ( doCollect && delcount > size / 2 ) // garbage collection { collect(); } } void collect() { if ( delcount > 0 ) { virgin = false; int nsize = size - delcount; if ( nsize == 0 ) { faid = null; fapos = null; } else { long[] nfaid = new long[nsize]; int[] nfapos = new int[nsize]; int idx = 0; byte[] nab = new byte[ab.length - delbytes]; int nab_off = 0; for( int i=0; i size ) p2size >>= 1; } } void unGhost() { ghost = false; delcount = 0; delbytes = 0; for( int i=0; i getPositions( OsmNodesMap nodesMap ) { ArrayList positions = new ArrayList(); for( int i=0; i