some more cleanup and performance squeezing
This commit is contained in:
parent
f70dd3c3ac
commit
12d8cae46f
16 changed files with 265 additions and 212 deletions
|
@ -22,7 +22,7 @@ public final class StatCoderContext extends BitCoderContext
|
|||
*/
|
||||
public void assignBits( String name )
|
||||
{
|
||||
long bitpos = getBitPosition();
|
||||
long bitpos = getWritingBitPosition();
|
||||
if ( statsPerName == null )
|
||||
{
|
||||
statsPerName = new TreeMap<String, long[]>();
|
||||
|
@ -88,12 +88,7 @@ public final class StatCoderContext extends BitCoderContext
|
|||
*/
|
||||
public int decodeNoisyNumber( int noisybits )
|
||||
{
|
||||
int value = 0;
|
||||
if ( noisybits > 0 )
|
||||
{
|
||||
int mask = 0xffffffff >>> ( 32 - noisybits );
|
||||
value = decodeBounded( mask );
|
||||
}
|
||||
int value = decodeBits( noisybits );
|
||||
return value | ( decodeVarBits() << noisybits );
|
||||
}
|
||||
|
||||
|
@ -130,8 +125,7 @@ public final class StatCoderContext extends BitCoderContext
|
|||
int value = 0;
|
||||
if ( noisybits > 0 )
|
||||
{
|
||||
int mask = 0xffffffff >>> ( 32 - noisybits );
|
||||
value = decodeBounded( mask ) - ( 1 << ( noisybits - 1 ) );
|
||||
value = decodeBits( noisybits ) - ( 1 << ( noisybits - 1 ) );
|
||||
}
|
||||
int val2 = decodeVarBits() << noisybits;
|
||||
if ( val2 != 0 )
|
||||
|
|
|
@ -99,26 +99,33 @@ public final class TagValueCoder
|
|||
node.child2 = decodeTree( bc, buffer, validator );
|
||||
return node;
|
||||
}
|
||||
BitCoderContext target = null;
|
||||
int startpos = bc.getReadingBitPosition();
|
||||
boolean hasdata = false;
|
||||
for ( ;; )
|
||||
{
|
||||
int delta = bc.decodeVarBits();
|
||||
if ( target == null )
|
||||
if ( !hasdata )
|
||||
{
|
||||
if ( delta == 0 )
|
||||
{
|
||||
return null;
|
||||
target = new BitCoderContext( buffer );
|
||||
target.encodeBit( false ); // dummy reverse bit
|
||||
}
|
||||
hasdata = true;
|
||||
}
|
||||
target.encodeVarBits( delta );
|
||||
if ( delta == 0 )
|
||||
{
|
||||
break;
|
||||
int data = bc.decodeVarBits();
|
||||
target.encodeVarBits( data );
|
||||
}
|
||||
bc.decodeVarBits();
|
||||
}
|
||||
int len = target.getEncodedLength();
|
||||
byte[] res = new byte[len];
|
||||
System.arraycopy( buffer, 0, res, 0, len );
|
||||
int endpos = bc.getReadingBitPosition();
|
||||
|
||||
int bitcount = endpos - startpos;
|
||||
int bytecount = ( bitcount + 7 ) >> 3;
|
||||
|
||||
bc.setReadingBitPosition( startpos );
|
||||
byte[] res = new byte[bytecount];
|
||||
bc.copyBitsTo( res, bitcount );
|
||||
|
||||
int accessType = validator == null ? 2 : validator.accessType( res );
|
||||
if ( accessType > 0 )
|
||||
|
@ -165,10 +172,6 @@ public final class TagValueCoder
|
|||
return;
|
||||
}
|
||||
BitCoderContext src = new BitCoderContext( data );
|
||||
if ( src.decodeBit() )
|
||||
{
|
||||
throw new IllegalArgumentException( "cannot encode reverse bit!" );
|
||||
}
|
||||
for ( ;; )
|
||||
{
|
||||
int delta = src.decodeVarBits();
|
||||
|
|
|
@ -47,7 +47,7 @@ final class OsmPath implements OsmLinkHolder
|
|||
public int originLon;
|
||||
public int originLat;
|
||||
|
||||
// the costfactor of the segment just before this paths position
|
||||
// the classifier of the segment just before this paths position
|
||||
public float lastClassifier;
|
||||
|
||||
public MessageData message;
|
||||
|
@ -129,6 +129,37 @@ final class OsmPath implements OsmLinkHolder
|
|||
|
||||
MessageData msgData = recordMessageData ? new MessageData() : null;
|
||||
|
||||
// evaluate the way tags
|
||||
rc.expctxWay.evaluate( rc.inverseDirection ^ link.counterLinkWritten, description );
|
||||
|
||||
// calculate the costfactor inputs
|
||||
boolean isTrafficBackbone = cost == 0 && rc.expctxWay.getIsTrafficBackbone() > 0.f;
|
||||
float turncostbase = rc.expctxWay.getTurncost();
|
||||
float cfup = rc.expctxWay.getUphillCostfactor();
|
||||
float cfdown = rc.expctxWay.getDownhillCostfactor();
|
||||
float cf = rc.expctxWay.getCostfactor();
|
||||
cfup = cfup == 0.f ? cf : cfup;
|
||||
cfdown = cfdown == 0.f ? cf : cfdown;
|
||||
|
||||
// *** add initial cost if the classifier changed
|
||||
float newClassifier = rc.expctxWay.getInitialClassifier();
|
||||
if ( newClassifier == 0. )
|
||||
{
|
||||
newClassifier = (cfup + cfdown + cf)/3;
|
||||
}
|
||||
float classifierDiff = newClassifier - lastClassifier;
|
||||
if ( classifierDiff > 0.0005 || classifierDiff < -0.0005 )
|
||||
{
|
||||
lastClassifier = newClassifier;
|
||||
float initialcost = rc.expctxWay.getInitialcost();
|
||||
int iicost = (int)initialcost;
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linkinitcost += iicost;
|
||||
}
|
||||
cost += iicost;
|
||||
}
|
||||
|
||||
OsmTransferNode transferNode = link.decodeFirsttransfer( p1 );
|
||||
OsmNode targetNode = link.targetNode;
|
||||
for(;;)
|
||||
|
@ -153,9 +184,7 @@ final class OsmPath implements OsmLinkHolder
|
|||
ele2 = transferNode.selev;
|
||||
}
|
||||
|
||||
boolean sameData = rc.expctxWay.evaluate( rc.inverseDirection ^ link.counterLinkWritten, description );
|
||||
|
||||
// if way description changed, store message
|
||||
// if recording, new MessageData for each section (needed for turn-instructions)
|
||||
if ( recordMessageData && msgData.wayKeyValues != null )
|
||||
{
|
||||
originElement.message = msgData;
|
||||
|
@ -199,18 +228,16 @@ final class OsmPath implements OsmLinkHolder
|
|||
}
|
||||
linkdisttotal += dist;
|
||||
|
||||
boolean isTrafficBackbone = cost == 0 && rc.expctxWay.getIsTrafficBackbone() > 0.f;
|
||||
|
||||
// *** penalty for turning angles
|
||||
if ( !isTrafficBackbone && origin.originElement != null )
|
||||
{
|
||||
// penalty proportional to direction change
|
||||
double cos = rc.calcCosAngle( lon0, lat0, lon1, lat1, lon2, lat2 );
|
||||
int turncost = (int)(cos * rc.expctxWay.getTurncost() + 0.2 ); // e.g. turncost=90 -> 90 degree = 90m penalty
|
||||
cost += turncost;
|
||||
int actualturncost = (int)(cos * turncostbase + 0.2 ); // e.g. turncost=90 -> 90 degree = 90m penalty
|
||||
cost += actualturncost;
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linkturncost += turncost;
|
||||
msgData.linkturncost += actualturncost;
|
||||
msgData.turnangle = (float)rc.calcAngle( lon0, lat0, lon1, lat1, lon2, lat2 );
|
||||
}
|
||||
}
|
||||
|
@ -292,16 +319,8 @@ final class OsmPath implements OsmLinkHolder
|
|||
ehbu = 0;
|
||||
}
|
||||
|
||||
// *** penalty for distance
|
||||
float cfup = rc.expctxWay.getUphillCostfactor();
|
||||
float cfdown = rc.expctxWay.getDownhillCostfactor();
|
||||
float cf = rc.expctxWay.getCostfactor();
|
||||
|
||||
cfup = cfup == 0.f ? cf : cfup;
|
||||
cfdown = cfdown == 0.f ? cf : cfdown;
|
||||
|
||||
// get the effective costfactor (slope dependent)
|
||||
float costfactor = cfup*upweight + cf*(1.f - upweight - downweight) + cfdown*downweight;
|
||||
|
||||
if ( isTrafficBackbone )
|
||||
{
|
||||
costfactor = 0.f;
|
||||
|
@ -323,24 +342,6 @@ final class OsmPath implements OsmLinkHolder
|
|||
int cost2 = cost < minDist ? minDist : cost;
|
||||
traffic += dist*rc.expctxWay.getTrafficSourceDensity()*Math.pow(cost2/10000.f,rc.trafficSourceExponent);
|
||||
}
|
||||
// *** add initial cost if the classifier changed
|
||||
float newClassifier = rc.expctxWay.getInitialClassifier();
|
||||
if ( newClassifier == 0. )
|
||||
{
|
||||
newClassifier = (cfup + cfdown + cf)/3;
|
||||
}
|
||||
float classifierDiff = newClassifier - lastClassifier;
|
||||
if ( classifierDiff > 0.0005 || classifierDiff < -0.0005 )
|
||||
{
|
||||
lastClassifier = newClassifier;
|
||||
float initialcost = rc.expctxWay.getInitialcost();
|
||||
int iicost = (int)initialcost;
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linkinitcost += iicost;
|
||||
}
|
||||
cost += iicost;
|
||||
}
|
||||
|
||||
if ( recordMessageData )
|
||||
{
|
||||
|
|
|
@ -63,8 +63,8 @@ public final class ProfileCache
|
|||
BExpressionMetaData meta = new BExpressionMetaData();
|
||||
|
||||
BExpressionContextGlobal expctxGlobal = new BExpressionContextGlobal( meta );
|
||||
rc.expctxWay = new BExpressionContextWay( rc.serversizing ? 262144 : 8192, meta );
|
||||
rc.expctxNode = new BExpressionContextNode( rc.serversizing ? 16384 : 2048, meta );
|
||||
rc.expctxWay = new BExpressionContextWay( rc.serversizing ? 262144 : 32768, meta );
|
||||
rc.expctxNode = new BExpressionContextNode( rc.serversizing ? 16384 : 4096, meta );
|
||||
|
||||
meta.readMetaData( new File( profileDir, "lookups.dat" ) );
|
||||
|
||||
|
|
|
@ -12,10 +12,8 @@ import java.util.List;
|
|||
import btools.expressions.BExpressionContext;
|
||||
import btools.expressions.BExpressionContextNode;
|
||||
import btools.expressions.BExpressionContextWay;
|
||||
import btools.mapaccess.DistanceChecker;
|
||||
import btools.mapaccess.OsmTransferNode;
|
||||
|
||||
public final class RoutingContext implements DistanceChecker
|
||||
public final class RoutingContext
|
||||
{
|
||||
public void setAlternativeIdx( int idx )
|
||||
{
|
||||
|
@ -349,28 +347,4 @@ public final class RoutingContext implements DistanceChecker
|
|||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWithinRadius( int ilon0, int ilat0, OsmTransferNode firstTransfer, int ilon1, int ilat1 )
|
||||
{
|
||||
OsmNodeNamed wp = nogopoints.get(0);
|
||||
double keepRadius = wp.radius;
|
||||
try
|
||||
{
|
||||
int ilon = ilon0;
|
||||
int ilat = ilat0;
|
||||
for( OsmTransferNode trans = firstTransfer; trans != null; trans = trans.next )
|
||||
{
|
||||
calcDistance( ilon, ilat, trans.ilon, trans.ilat );
|
||||
ilon = trans.ilon;
|
||||
ilat = trans.ilat;
|
||||
}
|
||||
calcDistance( ilon, ilat, ilon1, ilat1 );
|
||||
return wp.radius < keepRadius;
|
||||
}
|
||||
finally
|
||||
{
|
||||
wp.radius = keepRadius;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -226,10 +226,19 @@ public class RoutingEngine extends Thread
|
|||
}
|
||||
finally
|
||||
{
|
||||
if ( hasInfo() && routingContext.expctxWay != null )
|
||||
{
|
||||
logInfo( "expression cache stats=" + routingContext.expctxWay.cacheStats() );
|
||||
}
|
||||
|
||||
ProfileCache.releaseProfile( routingContext );
|
||||
|
||||
if ( nodesCache != null )
|
||||
{
|
||||
if ( hasInfo() && nodesCache != null )
|
||||
{
|
||||
logInfo( "NodesCache status before close=" + nodesCache.formatStatus() );
|
||||
}
|
||||
nodesCache.close();
|
||||
nodesCache = null;
|
||||
}
|
||||
|
@ -544,6 +553,10 @@ public class RoutingEngine extends Thread
|
|||
|
||||
private void resetCache()
|
||||
{
|
||||
if ( hasInfo() && nodesCache != null )
|
||||
{
|
||||
logInfo( "NodesCache status before reset=" + nodesCache.formatStatus() );
|
||||
}
|
||||
nodesMap = new OsmNodesMap();
|
||||
nodesCache = new NodesCache(segmentDir, nodesMap, routingContext.expctxWay, routingContext.carMode, routingContext.forceSecondaryData, nodesCache );
|
||||
}
|
||||
|
|
|
@ -49,12 +49,9 @@ public abstract class BExpressionContext
|
|||
|
||||
// hash-cache for function results
|
||||
private byte[][] _arrayBitmap;
|
||||
private boolean[] _arrayInverse;
|
||||
private int[] _arrayCrc;
|
||||
|
||||
private int currentHashBucket = -1;
|
||||
private byte[] currentByteArray = null;
|
||||
private boolean currentInverseDirection= false;
|
||||
|
||||
private List<BExpression> expressionList;
|
||||
|
||||
|
@ -98,17 +95,10 @@ public abstract class BExpressionContext
|
|||
|
||||
if ( Boolean.getBoolean( "disableExpressionCache" ) ) hashSize = 1;
|
||||
|
||||
// create the expression cache
|
||||
_arrayBitmap = new byte[hashSize][];
|
||||
_arrayInverse = new boolean[hashSize];
|
||||
_arrayCrc = new int[hashSize];
|
||||
|
||||
// create the build-in variables cache
|
||||
int nBuildInVars = getBuildInVariableNames().length;
|
||||
arrayBuildInVariablesCache = new float[hashSize][];
|
||||
for( int hi=0; hi<hashSize; hi++ )
|
||||
{
|
||||
arrayBuildInVariablesCache[hi] = new float[nBuildInVars];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,7 +114,6 @@ public abstract class BExpressionContext
|
|||
{
|
||||
// start with first bit hardwired ("reversedirection")
|
||||
BitCoderContext ctx = new BitCoderContext( abBuf );
|
||||
ctx.encodeBit( ld[0] != 0 );
|
||||
|
||||
int skippedTags = 0;
|
||||
int nonNullTags= 0;
|
||||
|
@ -159,7 +148,7 @@ public abstract class BExpressionContext
|
|||
// crosscheck: decode and compare
|
||||
int[] ld2 = new int[lookupValues.size()];
|
||||
decode( ld2, false, ab );
|
||||
for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names
|
||||
for( int inum = 1; inum < lookupValues.size(); inum++ ) // loop over lookup names (except reverse dir)
|
||||
{
|
||||
if ( ld2[inum] != ld[inum] ) throw new RuntimeException( "assertion failed encoding inum=" + inum + " val=" + ld[inum] + " " + getKeyValueDescription(false, ab) );
|
||||
}
|
||||
|
@ -185,7 +174,7 @@ public abstract class BExpressionContext
|
|||
BitCoderContext ctx = new BitCoderContext(ab);
|
||||
|
||||
// start with first bit hardwired ("reversedirection")
|
||||
ld[0] = inverseDirection ^ ctx.decodeBit() ? 2 : 0;
|
||||
ld[0] = inverseDirection ? 2 : 0;
|
||||
|
||||
// all others are generic
|
||||
int inum = 1;
|
||||
|
@ -270,72 +259,80 @@ public abstract class BExpressionContext
|
|||
}
|
||||
}
|
||||
|
||||
public long requests;
|
||||
public long requests2;
|
||||
public long cachemisses;
|
||||
private long requests;
|
||||
private long requests2;
|
||||
private long cachemisses;
|
||||
|
||||
public String cacheStats()
|
||||
{
|
||||
return "requests=" + requests + " requests2=" + requests2 + " cachemisses=" + cachemisses;
|
||||
}
|
||||
|
||||
/**
|
||||
* evaluates the data in the given byte array
|
||||
*
|
||||
* @return true if the data is equivilant to the last calls data
|
||||
*/
|
||||
public boolean evaluate( boolean inverseDirection, byte[] ab )
|
||||
public void evaluate( boolean inverseDirection, byte[] ab )
|
||||
{
|
||||
requests ++;
|
||||
lookupDataValid = false; // this is an assertion for a nasty pifall
|
||||
requests++;
|
||||
lookupDataValid = false; // this is an assertion for a nasty pifall
|
||||
|
||||
int inverseBitByteIndex = 0;
|
||||
// calc hash bucket from crc
|
||||
int crc = Crc32.crcWithInverseBit( ab, inverseDirection );
|
||||
int hashSize = _arrayBitmap.length;
|
||||
currentHashBucket = ( crc & 0xfffffff ) % hashSize;
|
||||
|
||||
// calc hash bucket from crc
|
||||
int lastHashBucket = currentHashBucket;
|
||||
int crc = Crc32.crcWithInverseBit(ab, inverseDirection ? inverseBitByteIndex : -1 );
|
||||
int hashSize = _arrayBitmap.length;
|
||||
currentHashBucket = (crc & 0xfffffff) % hashSize;
|
||||
hashBucketVars = arrayBuildInVariablesCache[currentHashBucket];
|
||||
currentByteArray = ab;
|
||||
currentInverseDirection = inverseDirection;
|
||||
byte[] abBucket = _arrayBitmap[currentHashBucket];
|
||||
boolean inverseBucket = _arrayInverse[currentHashBucket];
|
||||
if ( ab == abBucket && inverseBucket == inverseDirection ) // fast identity check
|
||||
{
|
||||
return lastHashBucket == currentHashBucket;
|
||||
}
|
||||
requests2++;
|
||||
int nBuildInVars = buildInVariableIdx.length;
|
||||
hashBucketVars = arrayBuildInVariablesCache[currentHashBucket];
|
||||
if ( hashBucketVars == null )
|
||||
{
|
||||
hashBucketVars = new float[nBuildInVars];
|
||||
arrayBuildInVariablesCache[currentHashBucket] = hashBucketVars;
|
||||
}
|
||||
|
||||
// compare input value to hash bucket content
|
||||
boolean hashBucketEquals = false;
|
||||
if ( crc == _arrayCrc[currentHashBucket] )
|
||||
{
|
||||
int abLen = ab.length;
|
||||
if ( abBucket != null && abBucket.length == ab.length )
|
||||
{
|
||||
hashBucketEquals = true;
|
||||
boolean isInverse = inverseDirection ^ inverseBucket;
|
||||
for( int i=0; i<abLen; i++ )
|
||||
{
|
||||
byte b = ab[i];
|
||||
if ( isInverse && i == inverseBitByteIndex ) b ^= 1;
|
||||
if ( abBucket[i] != b ) { hashBucketEquals = false; break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( hashBucketEquals ) return lastHashBucket == currentHashBucket;
|
||||
cachemisses++;
|
||||
if ( crc == _arrayCrc[currentHashBucket] )
|
||||
{
|
||||
byte[] abBucket = _arrayBitmap[currentHashBucket];
|
||||
if ( ab == abBucket ) // fast identity check
|
||||
{
|
||||
return;
|
||||
}
|
||||
requests2++;
|
||||
|
||||
_arrayBitmap[currentHashBucket] = currentByteArray;
|
||||
_arrayInverse[currentHashBucket] = currentInverseDirection;
|
||||
_arrayCrc[currentHashBucket] = crc;
|
||||
// compare input value to hash bucket content
|
||||
boolean hashBucketEquals = false;
|
||||
int abLen = ab.length;
|
||||
if ( abBucket != null && abBucket.length == abLen )
|
||||
{
|
||||
hashBucketEquals = true;
|
||||
for ( int i = 0; i < abLen; i++ )
|
||||
{
|
||||
if ( abBucket[i] != ab[i] )
|
||||
{
|
||||
hashBucketEquals = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( hashBucketEquals )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
cachemisses++;
|
||||
|
||||
decode( lookupData, currentInverseDirection, currentByteArray );
|
||||
evaluate( lookupData );
|
||||
_arrayBitmap[currentHashBucket] = ab;
|
||||
_arrayCrc[currentHashBucket] = crc;
|
||||
|
||||
for( int vi=0; vi<buildInVariableIdx.length; vi++ )
|
||||
{
|
||||
int idx = buildInVariableIdx[vi];
|
||||
hashBucketVars[vi] = idx == -1 ? 0.f : variableData[idx];
|
||||
}
|
||||
decode( lookupData, inverseDirection, ab );
|
||||
evaluate( lookupData );
|
||||
|
||||
return false;
|
||||
for ( int vi = 0; vi < nBuildInVars; vi++ )
|
||||
{
|
||||
int idx = buildInVariableIdx[vi];
|
||||
hashBucketVars[vi] = idx == -1 ? 0.f : variableData[idx];
|
||||
}
|
||||
}
|
||||
|
||||
public void dumpStatistics()
|
||||
|
|
|
@ -39,7 +39,7 @@ public class EncodeDecodeTest
|
|||
byte[] description = expctxWay.encode(lookupData);
|
||||
|
||||
// calculate the cost factor from that description
|
||||
expctxWay.evaluate( false, description );
|
||||
expctxWay.evaluate( true, description ); // true = "reversedirection=yes" (not encoded in description anymore)
|
||||
|
||||
float costfactor = expctxWay.getCostfactor();
|
||||
Assert.assertTrue( "costfactor mismatch", Math.abs( costfactor - 5.15 ) < 0.00001 );
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
/**
|
||||
* Container for routig configs
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
package btools.mapaccess;
|
||||
|
||||
public interface DistanceChecker
|
||||
{
|
||||
/**
|
||||
* Checks whether the given path is within a maximum distance
|
||||
* known to the distance checker
|
||||
* @return true if close enough
|
||||
*/
|
||||
boolean isWithinRadius( int ilon0, int ilat0, OsmTransferNode firstTransfer, int ilon1, int ilat1 );
|
||||
}
|
|
@ -43,6 +43,11 @@ public final class NodesCache
|
|||
private long cacheSum = 0;
|
||||
private boolean garbageCollectionEnabled = false;
|
||||
|
||||
public String formatStatus()
|
||||
{
|
||||
return "collecting=" + garbageCollectionEnabled + " cacheSum=" + cacheSum;
|
||||
}
|
||||
|
||||
public NodesCache( String segmentDir, OsmNodesMap nodesMap, BExpressionContextWay ctxWay, boolean carMode, boolean forceSecondaryData,
|
||||
NodesCache oldCache )
|
||||
{
|
||||
|
@ -91,7 +96,7 @@ public final class NodesCache
|
|||
// clean all ghosts and enable garbage collection
|
||||
private void checkEnableCacheCleaning()
|
||||
{
|
||||
if ( cacheSum < 500000 || garbageCollectionEnabled )
|
||||
if ( cacheSum < 3000000 || garbageCollectionEnabled )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < fileRows.length; i++ )
|
||||
|
|
|
@ -178,8 +178,7 @@ public class OsmNode implements OsmPos
|
|||
OsmLink link = getCompatibleLink( linklon, linklat, isReverse, 2 );
|
||||
if ( link == null ) // .. not found, then check the hollow nodes
|
||||
{
|
||||
long targetNodeId = ( (long) linklon ) << 32 | linklat;
|
||||
OsmNode tn = hollowNodes.get( targetNodeId ); // target node
|
||||
OsmNode tn = hollowNodes.get( linklon, linklat ); // target node
|
||||
if ( tn == null ) // node not yet known, create a new hollow proxy
|
||||
{
|
||||
tn = new OsmNode( linklon, linklat );
|
||||
|
|
|
@ -26,10 +26,10 @@ public final class OsmNodesMap
|
|||
* Get a node from the map
|
||||
* @return the node for the given id if exist, else null
|
||||
*/
|
||||
public OsmNode get( long id )
|
||||
public OsmNode get( int ilon, int ilat )
|
||||
{
|
||||
testKey.ilon = (int)(id >> 32);
|
||||
testKey.ilat = (int)(id & 0xffffffff);
|
||||
testKey.ilon = ilon;
|
||||
testKey.ilat = ilat;
|
||||
return hmap.get( testKey );
|
||||
}
|
||||
|
||||
|
@ -48,13 +48,4 @@ public final class OsmNodesMap
|
|||
return hmap.put( node, node );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the number of nodes in that map
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
return hmap.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public class TwinRoutingEngine extends RoutingEngine
|
|||
System.out.println( "linksProcessed=" + router.linksProcessed + " linksReProcessed=" + router.linksReProcessed);
|
||||
System.out.println( "skippedChained=" + router.skippedChained + " closedSkippedChained=" + router.closedSkippedChained);
|
||||
|
||||
System.out.println( "expCtxWay: requests: " + routingContext.expctxWay.requests + " requests2: " + routingContext.expctxWay.requests2 + " cache-misses: " + routingContext.expctxWay.cachemisses );
|
||||
System.out.println( "expCtxWay: requests: " + routingContext.expctxWay.cacheStats() );
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,16 @@ package btools.util;
|
|||
public class BitCoderContext
|
||||
{
|
||||
private byte[] ab;
|
||||
private int idxMax;
|
||||
private int idx = -1;
|
||||
private int bm = 0x100; // byte mask
|
||||
private int bm = 0x100; // byte mask (write mode)
|
||||
private int bits; // bits left in buffer (read mode)
|
||||
private int b;
|
||||
|
||||
public BitCoderContext( byte[] ab )
|
||||
{
|
||||
this.ab = ab;
|
||||
idxMax = ab.length-1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,18 +42,32 @@ public class BitCoderContext
|
|||
/**
|
||||
* @see #encodeVarBits
|
||||
*/
|
||||
public final int decodeVarBits()
|
||||
public final int decodeVarBits2()
|
||||
{
|
||||
int range = 0;
|
||||
int value = 0;
|
||||
while (!decodeBit())
|
||||
{
|
||||
value += range + 1;
|
||||
range = 2 * range + 1;
|
||||
}
|
||||
return value + decodeBounded( range );
|
||||
return range + decodeBounded( range );
|
||||
}
|
||||
|
||||
public final int decodeVarBits()
|
||||
{
|
||||
int range = 1;
|
||||
int cnt = 1;
|
||||
fillBuffer();
|
||||
while ((b & range) == 0)
|
||||
{
|
||||
range = (range << 1) | 1;
|
||||
cnt++;
|
||||
}
|
||||
b >>>= cnt;
|
||||
bits -= cnt;
|
||||
return (range >>> 1) + ( cnt > 1 ? decodeBits( cnt-1 ) : 0 );
|
||||
}
|
||||
|
||||
|
||||
public final void encodeBit( boolean value )
|
||||
{
|
||||
if ( bm == 0x100 )
|
||||
|
@ -65,13 +82,14 @@ public class BitCoderContext
|
|||
|
||||
public final boolean decodeBit()
|
||||
{
|
||||
if ( bm == 0x100 )
|
||||
if ( bits == 0 )
|
||||
{
|
||||
bm = 1;
|
||||
b = ab[++idx];
|
||||
bits = 8;
|
||||
b = ab[++idx] & 0xff;
|
||||
}
|
||||
boolean value = ( ( b & bm ) != 0 );
|
||||
bm <<= 1;
|
||||
boolean value = ( ( b & 1 ) != 0 );
|
||||
b >>>= 1;
|
||||
bits--;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -111,19 +129,46 @@ public class BitCoderContext
|
|||
int im = 1; // integer mask
|
||||
while (( value | im ) <= max)
|
||||
{
|
||||
if ( bm == 0x100 )
|
||||
if ( bits == 0 )
|
||||
{
|
||||
bm = 1;
|
||||
b = ab[++idx];
|
||||
bits = 8;
|
||||
b = ab[++idx] & 0xff;
|
||||
}
|
||||
if ( ( b & bm ) != 0 )
|
||||
if ( ( b & 1 ) != 0 )
|
||||
value |= im;
|
||||
bm <<= 1;
|
||||
b >>>= 1;
|
||||
bits--;
|
||||
im <<= 1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public final int decodeBits( int count )
|
||||
{
|
||||
if ( count == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fillBuffer();
|
||||
int mask = 0xffffffff >>> ( 32 - count );
|
||||
int value = b & mask;
|
||||
b >>>= count;
|
||||
bits -= count;
|
||||
return value;
|
||||
}
|
||||
|
||||
private void fillBuffer()
|
||||
{
|
||||
while (bits < 24)
|
||||
{
|
||||
if ( idx < idxMax )
|
||||
{
|
||||
b |= (ab[++idx] & 0xff) << bits;
|
||||
}
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the encoded length in bytes
|
||||
*/
|
||||
|
@ -135,7 +180,7 @@ public class BitCoderContext
|
|||
/**
|
||||
* @return the encoded length in bits
|
||||
*/
|
||||
public final long getBitPosition()
|
||||
public final long getWritingBitPosition()
|
||||
{
|
||||
long bitpos = idx << 3;
|
||||
int m = bm;
|
||||
|
@ -147,4 +192,53 @@ public class BitCoderContext
|
|||
return bitpos;
|
||||
}
|
||||
|
||||
public final int getReadingBitPosition()
|
||||
{
|
||||
return (idx << 3) + 8 - bits;
|
||||
}
|
||||
|
||||
public final void setReadingBitPosition(int pos)
|
||||
{
|
||||
idx = pos >>> 3;
|
||||
bits = (idx << 3) + 8 - pos;
|
||||
b = ab[idx] & 0xff;
|
||||
b >>>= (8-bits);
|
||||
}
|
||||
|
||||
public final void copyBitsTo( byte[] dst, int bitcount )
|
||||
{
|
||||
int dstIdx = 0;
|
||||
for(;;)
|
||||
{
|
||||
if ( bitcount > 8 )
|
||||
{
|
||||
if ( bits < 8 )
|
||||
{
|
||||
b |= (ab[++idx] & 0xff) << bits;
|
||||
}
|
||||
else
|
||||
{
|
||||
bits -= 8;
|
||||
}
|
||||
dst[dstIdx++] = (byte)b;
|
||||
b >>>= 8;
|
||||
bitcount -= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bits < bitcount )
|
||||
{
|
||||
b |= (ab[++idx] & 0xff) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
|
||||
int mask = 0xff >>> ( 8 - bitcount );
|
||||
dst[dstIdx] = (byte)(b & mask);
|
||||
bits -= bitcount;
|
||||
b >>>= bitcount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,17 +30,15 @@ public class Crc32
|
|||
return crc;
|
||||
}
|
||||
|
||||
public static int crcWithInverseBit( byte[] ab, int inverseBitByteIndex )
|
||||
public static int crcWithInverseBit( byte[] ab, boolean isInverse )
|
||||
{
|
||||
int crc = 0xFFFFFFFF;
|
||||
int crc = 0xFFFFFF ^ ( isInverse ? 0x990951ba : 0x706af48f ); // inverse is webbed into crc...
|
||||
int end = ab.length;
|
||||
for( int j=0; j<end; j++ )
|
||||
{
|
||||
byte b = ab[j];
|
||||
if ( j == inverseBitByteIndex ) b ^= 1;
|
||||
crc = (crc >>> 8) ^ crctable[(crc ^ b) & 0xff];
|
||||
crc = (crc >>> 8) ^ crctable[(crc ^ ab[j]) & 0xff];
|
||||
}
|
||||
return crc;
|
||||
return isInverse ? crc | 0x80000000 : crc & 0x7fffffff; // ... and set as high bit
|
||||
}
|
||||
|
||||
private static int[] crctable = {
|
||||
|
|
|
@ -19,7 +19,7 @@ public class BitCoderContextTest
|
|||
for ( int i = 0; i < 1000; i++ )
|
||||
{
|
||||
int value = ctx.decodeVarBits();
|
||||
Assert.assertTrue( "distance value mismatch", value == i );
|
||||
Assert.assertTrue( "distance value mismatch i=" + i + "v=" + value, value == i );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue