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 )
|
public void assignBits( String name )
|
||||||
{
|
{
|
||||||
long bitpos = getBitPosition();
|
long bitpos = getWritingBitPosition();
|
||||||
if ( statsPerName == null )
|
if ( statsPerName == null )
|
||||||
{
|
{
|
||||||
statsPerName = new TreeMap<String, long[]>();
|
statsPerName = new TreeMap<String, long[]>();
|
||||||
|
@ -88,12 +88,7 @@ public final class StatCoderContext extends BitCoderContext
|
||||||
*/
|
*/
|
||||||
public int decodeNoisyNumber( int noisybits )
|
public int decodeNoisyNumber( int noisybits )
|
||||||
{
|
{
|
||||||
int value = 0;
|
int value = decodeBits( noisybits );
|
||||||
if ( noisybits > 0 )
|
|
||||||
{
|
|
||||||
int mask = 0xffffffff >>> ( 32 - noisybits );
|
|
||||||
value = decodeBounded( mask );
|
|
||||||
}
|
|
||||||
return value | ( decodeVarBits() << noisybits );
|
return value | ( decodeVarBits() << noisybits );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +125,7 @@ public final class StatCoderContext extends BitCoderContext
|
||||||
int value = 0;
|
int value = 0;
|
||||||
if ( noisybits > 0 )
|
if ( noisybits > 0 )
|
||||||
{
|
{
|
||||||
int mask = 0xffffffff >>> ( 32 - noisybits );
|
value = decodeBits( noisybits ) - ( 1 << ( noisybits - 1 ) );
|
||||||
value = decodeBounded( mask ) - ( 1 << ( noisybits - 1 ) );
|
|
||||||
}
|
}
|
||||||
int val2 = decodeVarBits() << noisybits;
|
int val2 = decodeVarBits() << noisybits;
|
||||||
if ( val2 != 0 )
|
if ( val2 != 0 )
|
||||||
|
|
|
@ -99,26 +99,33 @@ public final class TagValueCoder
|
||||||
node.child2 = decodeTree( bc, buffer, validator );
|
node.child2 = decodeTree( bc, buffer, validator );
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
BitCoderContext target = null;
|
int startpos = bc.getReadingBitPosition();
|
||||||
|
boolean hasdata = false;
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
int delta = bc.decodeVarBits();
|
int delta = bc.decodeVarBits();
|
||||||
if ( target == null )
|
if ( !hasdata )
|
||||||
{
|
{
|
||||||
if ( delta == 0 )
|
if ( delta == 0 )
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
target = new BitCoderContext( buffer );
|
}
|
||||||
target.encodeBit( false ); // dummy reverse bit
|
hasdata = true;
|
||||||
}
|
}
|
||||||
target.encodeVarBits( delta );
|
|
||||||
if ( delta == 0 )
|
if ( delta == 0 )
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
int data = bc.decodeVarBits();
|
}
|
||||||
target.encodeVarBits( data );
|
bc.decodeVarBits();
|
||||||
}
|
}
|
||||||
int len = target.getEncodedLength();
|
int endpos = bc.getReadingBitPosition();
|
||||||
byte[] res = new byte[len];
|
|
||||||
System.arraycopy( buffer, 0, res, 0, len );
|
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 );
|
int accessType = validator == null ? 2 : validator.accessType( res );
|
||||||
if ( accessType > 0 )
|
if ( accessType > 0 )
|
||||||
|
@ -165,10 +172,6 @@ public final class TagValueCoder
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BitCoderContext src = new BitCoderContext( data );
|
BitCoderContext src = new BitCoderContext( data );
|
||||||
if ( src.decodeBit() )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( "cannot encode reverse bit!" );
|
|
||||||
}
|
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
int delta = src.decodeVarBits();
|
int delta = src.decodeVarBits();
|
||||||
|
|
|
@ -47,7 +47,7 @@ final class OsmPath implements OsmLinkHolder
|
||||||
public int originLon;
|
public int originLon;
|
||||||
public int originLat;
|
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 float lastClassifier;
|
||||||
|
|
||||||
public MessageData message;
|
public MessageData message;
|
||||||
|
@ -129,6 +129,37 @@ final class OsmPath implements OsmLinkHolder
|
||||||
|
|
||||||
MessageData msgData = recordMessageData ? new MessageData() : null;
|
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 );
|
OsmTransferNode transferNode = link.decodeFirsttransfer( p1 );
|
||||||
OsmNode targetNode = link.targetNode;
|
OsmNode targetNode = link.targetNode;
|
||||||
for(;;)
|
for(;;)
|
||||||
|
@ -152,10 +183,8 @@ final class OsmPath implements OsmLinkHolder
|
||||||
lat2 = transferNode.ilat;
|
lat2 = transferNode.ilat;
|
||||||
ele2 = transferNode.selev;
|
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 )
|
if ( recordMessageData && msgData.wayKeyValues != null )
|
||||||
{
|
{
|
||||||
originElement.message = msgData;
|
originElement.message = msgData;
|
||||||
|
@ -199,18 +228,16 @@ final class OsmPath implements OsmLinkHolder
|
||||||
}
|
}
|
||||||
linkdisttotal += dist;
|
linkdisttotal += dist;
|
||||||
|
|
||||||
boolean isTrafficBackbone = cost == 0 && rc.expctxWay.getIsTrafficBackbone() > 0.f;
|
|
||||||
|
|
||||||
// *** penalty for turning angles
|
// *** penalty for turning angles
|
||||||
if ( !isTrafficBackbone && origin.originElement != null )
|
if ( !isTrafficBackbone && origin.originElement != null )
|
||||||
{
|
{
|
||||||
// penalty proportional to direction change
|
// penalty proportional to direction change
|
||||||
double cos = rc.calcCosAngle( lon0, lat0, lon1, lat1, lon2, lat2 );
|
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
|
int actualturncost = (int)(cos * turncostbase + 0.2 ); // e.g. turncost=90 -> 90 degree = 90m penalty
|
||||||
cost += turncost;
|
cost += actualturncost;
|
||||||
if ( recordMessageData )
|
if ( recordMessageData )
|
||||||
{
|
{
|
||||||
msgData.linkturncost += turncost;
|
msgData.linkturncost += actualturncost;
|
||||||
msgData.turnangle = (float)rc.calcAngle( lon0, lat0, lon1, lat1, lon2, lat2 );
|
msgData.turnangle = (float)rc.calcAngle( lon0, lat0, lon1, lat1, lon2, lat2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,16 +319,8 @@ final class OsmPath implements OsmLinkHolder
|
||||||
ehbu = 0;
|
ehbu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// *** penalty for distance
|
// get the effective costfactor (slope dependent)
|
||||||
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;
|
|
||||||
|
|
||||||
float costfactor = cfup*upweight + cf*(1.f - upweight - downweight) + cfdown*downweight;
|
float costfactor = cfup*upweight + cf*(1.f - upweight - downweight) + cfdown*downweight;
|
||||||
|
|
||||||
if ( isTrafficBackbone )
|
if ( isTrafficBackbone )
|
||||||
{
|
{
|
||||||
costfactor = 0.f;
|
costfactor = 0.f;
|
||||||
|
@ -323,24 +342,6 @@ final class OsmPath implements OsmLinkHolder
|
||||||
int cost2 = cost < minDist ? minDist : cost;
|
int cost2 = cost < minDist ? minDist : cost;
|
||||||
traffic += dist*rc.expctxWay.getTrafficSourceDensity()*Math.pow(cost2/10000.f,rc.trafficSourceExponent);
|
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 )
|
if ( recordMessageData )
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,8 +63,8 @@ public final class ProfileCache
|
||||||
BExpressionMetaData meta = new BExpressionMetaData();
|
BExpressionMetaData meta = new BExpressionMetaData();
|
||||||
|
|
||||||
BExpressionContextGlobal expctxGlobal = new BExpressionContextGlobal( meta );
|
BExpressionContextGlobal expctxGlobal = new BExpressionContextGlobal( meta );
|
||||||
rc.expctxWay = new BExpressionContextWay( rc.serversizing ? 262144 : 8192, meta );
|
rc.expctxWay = new BExpressionContextWay( rc.serversizing ? 262144 : 32768, meta );
|
||||||
rc.expctxNode = new BExpressionContextNode( rc.serversizing ? 16384 : 2048, meta );
|
rc.expctxNode = new BExpressionContextNode( rc.serversizing ? 16384 : 4096, meta );
|
||||||
|
|
||||||
meta.readMetaData( new File( profileDir, "lookups.dat" ) );
|
meta.readMetaData( new File( profileDir, "lookups.dat" ) );
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,8 @@ import java.util.List;
|
||||||
import btools.expressions.BExpressionContext;
|
import btools.expressions.BExpressionContext;
|
||||||
import btools.expressions.BExpressionContextNode;
|
import btools.expressions.BExpressionContextNode;
|
||||||
import btools.expressions.BExpressionContextWay;
|
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 )
|
public void setAlternativeIdx( int idx )
|
||||||
{
|
{
|
||||||
|
@ -349,28 +347,4 @@ public final class RoutingContext implements DistanceChecker
|
||||||
return p;
|
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
|
finally
|
||||||
{
|
{
|
||||||
ProfileCache.releaseProfile( routingContext );
|
if ( hasInfo() && routingContext.expctxWay != null )
|
||||||
|
{
|
||||||
|
logInfo( "expression cache stats=" + routingContext.expctxWay.cacheStats() );
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileCache.releaseProfile( routingContext );
|
||||||
|
|
||||||
if ( nodesCache != null )
|
if ( nodesCache != null )
|
||||||
{
|
{
|
||||||
|
if ( hasInfo() && nodesCache != null )
|
||||||
|
{
|
||||||
|
logInfo( "NodesCache status before close=" + nodesCache.formatStatus() );
|
||||||
|
}
|
||||||
nodesCache.close();
|
nodesCache.close();
|
||||||
nodesCache = null;
|
nodesCache = null;
|
||||||
}
|
}
|
||||||
|
@ -544,6 +553,10 @@ public class RoutingEngine extends Thread
|
||||||
|
|
||||||
private void resetCache()
|
private void resetCache()
|
||||||
{
|
{
|
||||||
|
if ( hasInfo() && nodesCache != null )
|
||||||
|
{
|
||||||
|
logInfo( "NodesCache status before reset=" + nodesCache.formatStatus() );
|
||||||
|
}
|
||||||
nodesMap = new OsmNodesMap();
|
nodesMap = new OsmNodesMap();
|
||||||
nodesCache = new NodesCache(segmentDir, nodesMap, routingContext.expctxWay, routingContext.carMode, routingContext.forceSecondaryData, nodesCache );
|
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
|
// hash-cache for function results
|
||||||
private byte[][] _arrayBitmap;
|
private byte[][] _arrayBitmap;
|
||||||
private boolean[] _arrayInverse;
|
|
||||||
private int[] _arrayCrc;
|
private int[] _arrayCrc;
|
||||||
|
|
||||||
private int currentHashBucket = -1;
|
private int currentHashBucket = -1;
|
||||||
private byte[] currentByteArray = null;
|
|
||||||
private boolean currentInverseDirection= false;
|
|
||||||
|
|
||||||
private List<BExpression> expressionList;
|
private List<BExpression> expressionList;
|
||||||
|
|
||||||
|
@ -98,17 +95,10 @@ public abstract class BExpressionContext
|
||||||
|
|
||||||
if ( Boolean.getBoolean( "disableExpressionCache" ) ) hashSize = 1;
|
if ( Boolean.getBoolean( "disableExpressionCache" ) ) hashSize = 1;
|
||||||
|
|
||||||
|
// create the expression cache
|
||||||
_arrayBitmap = new byte[hashSize][];
|
_arrayBitmap = new byte[hashSize][];
|
||||||
_arrayInverse = new boolean[hashSize];
|
|
||||||
_arrayCrc = new int[hashSize];
|
_arrayCrc = new int[hashSize];
|
||||||
|
|
||||||
// create the build-in variables cache
|
|
||||||
int nBuildInVars = getBuildInVariableNames().length;
|
|
||||||
arrayBuildInVariablesCache = new float[hashSize][];
|
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")
|
// start with first bit hardwired ("reversedirection")
|
||||||
BitCoderContext ctx = new BitCoderContext( abBuf );
|
BitCoderContext ctx = new BitCoderContext( abBuf );
|
||||||
ctx.encodeBit( ld[0] != 0 );
|
|
||||||
|
|
||||||
int skippedTags = 0;
|
int skippedTags = 0;
|
||||||
int nonNullTags= 0;
|
int nonNullTags= 0;
|
||||||
|
@ -159,7 +148,7 @@ public abstract class BExpressionContext
|
||||||
// crosscheck: decode and compare
|
// crosscheck: decode and compare
|
||||||
int[] ld2 = new int[lookupValues.size()];
|
int[] ld2 = new int[lookupValues.size()];
|
||||||
decode( ld2, false, ab );
|
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) );
|
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);
|
BitCoderContext ctx = new BitCoderContext(ab);
|
||||||
|
|
||||||
// start with first bit hardwired ("reversedirection")
|
// start with first bit hardwired ("reversedirection")
|
||||||
ld[0] = inverseDirection ^ ctx.decodeBit() ? 2 : 0;
|
ld[0] = inverseDirection ? 2 : 0;
|
||||||
|
|
||||||
// all others are generic
|
// all others are generic
|
||||||
int inum = 1;
|
int inum = 1;
|
||||||
|
@ -270,72 +259,80 @@ public abstract class BExpressionContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long requests;
|
private long requests;
|
||||||
public long requests2;
|
private long requests2;
|
||||||
public long cachemisses;
|
private long cachemisses;
|
||||||
|
|
||||||
|
public String cacheStats()
|
||||||
|
{
|
||||||
|
return "requests=" + requests + " requests2=" + requests2 + " cachemisses=" + cachemisses;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* evaluates the data in the given byte array
|
* evaluates the data in the given byte array
|
||||||
*
|
*
|
||||||
* @return true if the data is equivilant to the last calls data
|
* @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 ++;
|
requests++;
|
||||||
lookupDataValid = false; // this is an assertion for a nasty pifall
|
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;
|
||||||
|
|
||||||
|
int nBuildInVars = buildInVariableIdx.length;
|
||||||
|
hashBucketVars = arrayBuildInVariablesCache[currentHashBucket];
|
||||||
|
if ( hashBucketVars == null )
|
||||||
|
{
|
||||||
|
hashBucketVars = new float[nBuildInVars];
|
||||||
|
arrayBuildInVariablesCache[currentHashBucket] = hashBucketVars;
|
||||||
|
}
|
||||||
|
|
||||||
// calc hash bucket from crc
|
if ( crc == _arrayCrc[currentHashBucket] )
|
||||||
int lastHashBucket = currentHashBucket;
|
{
|
||||||
int crc = Crc32.crcWithInverseBit(ab, inverseDirection ? inverseBitByteIndex : -1 );
|
byte[] abBucket = _arrayBitmap[currentHashBucket];
|
||||||
int hashSize = _arrayBitmap.length;
|
if ( ab == abBucket ) // fast identity check
|
||||||
currentHashBucket = (crc & 0xfffffff) % hashSize;
|
{
|
||||||
hashBucketVars = arrayBuildInVariablesCache[currentHashBucket];
|
return;
|
||||||
currentByteArray = ab;
|
}
|
||||||
currentInverseDirection = inverseDirection;
|
requests2++;
|
||||||
byte[] abBucket = _arrayBitmap[currentHashBucket];
|
|
||||||
boolean inverseBucket = _arrayInverse[currentHashBucket];
|
|
||||||
if ( ab == abBucket && inverseBucket == inverseDirection ) // fast identity check
|
|
||||||
{
|
|
||||||
return lastHashBucket == currentHashBucket;
|
|
||||||
}
|
|
||||||
requests2++;
|
|
||||||
|
|
||||||
// compare input value to hash bucket content
|
// compare input value to hash bucket content
|
||||||
boolean hashBucketEquals = false;
|
boolean hashBucketEquals = false;
|
||||||
if ( crc == _arrayCrc[currentHashBucket] )
|
int abLen = ab.length;
|
||||||
{
|
if ( abBucket != null && abBucket.length == abLen )
|
||||||
int abLen = ab.length;
|
{
|
||||||
if ( abBucket != null && abBucket.length == ab.length )
|
hashBucketEquals = true;
|
||||||
{
|
for ( int i = 0; i < abLen; i++ )
|
||||||
hashBucketEquals = true;
|
{
|
||||||
boolean isInverse = inverseDirection ^ inverseBucket;
|
if ( abBucket[i] != ab[i] )
|
||||||
for( int i=0; i<abLen; i++ )
|
{
|
||||||
{
|
hashBucketEquals = false;
|
||||||
byte b = ab[i];
|
break;
|
||||||
if ( isInverse && i == inverseBitByteIndex ) b ^= 1;
|
}
|
||||||
if ( abBucket[i] != b ) { hashBucketEquals = false; break; }
|
}
|
||||||
}
|
}
|
||||||
}
|
if ( hashBucketEquals )
|
||||||
}
|
{
|
||||||
if ( hashBucketEquals ) return lastHashBucket == currentHashBucket;
|
return;
|
||||||
cachemisses++;
|
}
|
||||||
|
}
|
||||||
_arrayBitmap[currentHashBucket] = currentByteArray;
|
cachemisses++;
|
||||||
_arrayInverse[currentHashBucket] = currentInverseDirection;
|
|
||||||
_arrayCrc[currentHashBucket] = crc;
|
|
||||||
|
|
||||||
decode( lookupData, currentInverseDirection, currentByteArray );
|
_arrayBitmap[currentHashBucket] = ab;
|
||||||
evaluate( lookupData );
|
_arrayCrc[currentHashBucket] = crc;
|
||||||
|
|
||||||
for( int vi=0; vi<buildInVariableIdx.length; vi++ )
|
decode( lookupData, inverseDirection, ab );
|
||||||
{
|
evaluate( lookupData );
|
||||||
int idx = buildInVariableIdx[vi];
|
|
||||||
hashBucketVars[vi] = idx == -1 ? 0.f : variableData[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
for ( int vi = 0; vi < nBuildInVars; vi++ )
|
||||||
|
{
|
||||||
|
int idx = buildInVariableIdx[vi];
|
||||||
|
hashBucketVars[vi] = idx == -1 ? 0.f : variableData[idx];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dumpStatistics()
|
public void dumpStatistics()
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class EncodeDecodeTest
|
||||||
byte[] description = expctxWay.encode(lookupData);
|
byte[] description = expctxWay.encode(lookupData);
|
||||||
|
|
||||||
// calculate the cost factor from that description
|
// 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();
|
float costfactor = expctxWay.getCostfactor();
|
||||||
Assert.assertTrue( "costfactor mismatch", Math.abs( costfactor - 5.15 ) < 0.00001 );
|
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 );
|
|
||||||
}
|
|
|
@ -42,6 +42,11 @@ public final class NodesCache
|
||||||
|
|
||||||
private long cacheSum = 0;
|
private long cacheSum = 0;
|
||||||
private boolean garbageCollectionEnabled = false;
|
private boolean garbageCollectionEnabled = false;
|
||||||
|
|
||||||
|
public String formatStatus()
|
||||||
|
{
|
||||||
|
return "collecting=" + garbageCollectionEnabled + " cacheSum=" + cacheSum;
|
||||||
|
}
|
||||||
|
|
||||||
public NodesCache( String segmentDir, OsmNodesMap nodesMap, BExpressionContextWay ctxWay, boolean carMode, boolean forceSecondaryData,
|
public NodesCache( String segmentDir, OsmNodesMap nodesMap, BExpressionContextWay ctxWay, boolean carMode, boolean forceSecondaryData,
|
||||||
NodesCache oldCache )
|
NodesCache oldCache )
|
||||||
|
@ -91,7 +96,7 @@ public final class NodesCache
|
||||||
// clean all ghosts and enable garbage collection
|
// clean all ghosts and enable garbage collection
|
||||||
private void checkEnableCacheCleaning()
|
private void checkEnableCacheCleaning()
|
||||||
{
|
{
|
||||||
if ( cacheSum < 500000 || garbageCollectionEnabled )
|
if ( cacheSum < 3000000 || garbageCollectionEnabled )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for ( int i = 0; i < fileRows.length; i++ )
|
for ( int i = 0; i < fileRows.length; i++ )
|
||||||
|
|
|
@ -178,8 +178,7 @@ public class OsmNode implements OsmPos
|
||||||
OsmLink link = getCompatibleLink( linklon, linklat, isReverse, 2 );
|
OsmLink link = getCompatibleLink( linklon, linklat, isReverse, 2 );
|
||||||
if ( link == null ) // .. not found, then check the hollow nodes
|
if ( link == null ) // .. not found, then check the hollow nodes
|
||||||
{
|
{
|
||||||
long targetNodeId = ( (long) linklon ) << 32 | linklat;
|
OsmNode tn = hollowNodes.get( linklon, linklat ); // target node
|
||||||
OsmNode tn = hollowNodes.get( targetNodeId ); // target node
|
|
||||||
if ( tn == null ) // node not yet known, create a new hollow proxy
|
if ( tn == null ) // node not yet known, create a new hollow proxy
|
||||||
{
|
{
|
||||||
tn = new OsmNode( linklon, linklat );
|
tn = new OsmNode( linklon, linklat );
|
||||||
|
|
|
@ -26,10 +26,10 @@ public final class OsmNodesMap
|
||||||
* Get a node from the map
|
* Get a node from the map
|
||||||
* @return the node for the given id if exist, else null
|
* @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.ilon = ilon;
|
||||||
testKey.ilat = (int)(id & 0xffffffff);
|
testKey.ilat = ilat;
|
||||||
return hmap.get( testKey );
|
return hmap.get( testKey );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,13 +48,4 @@ public final class OsmNodesMap
|
||||||
return hmap.put( node, node );
|
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( "linksProcessed=" + router.linksProcessed + " linksReProcessed=" + router.linksReProcessed);
|
||||||
System.out.println( "skippedChained=" + router.skippedChained + " closedSkippedChained=" + router.closedSkippedChained);
|
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
|
public class BitCoderContext
|
||||||
{
|
{
|
||||||
private byte[] ab;
|
private byte[] ab;
|
||||||
|
private int idxMax;
|
||||||
private int idx = -1;
|
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;
|
private int b;
|
||||||
|
|
||||||
public BitCoderContext( byte[] ab )
|
public BitCoderContext( byte[] ab )
|
||||||
{
|
{
|
||||||
this.ab = ab;
|
this.ab = ab;
|
||||||
|
idxMax = ab.length-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,18 +42,32 @@ public class BitCoderContext
|
||||||
/**
|
/**
|
||||||
* @see #encodeVarBits
|
* @see #encodeVarBits
|
||||||
*/
|
*/
|
||||||
public final int decodeVarBits()
|
public final int decodeVarBits2()
|
||||||
{
|
{
|
||||||
int range = 0;
|
int range = 0;
|
||||||
int value = 0;
|
|
||||||
while (!decodeBit())
|
while (!decodeBit())
|
||||||
{
|
{
|
||||||
value += range + 1;
|
|
||||||
range = 2 * 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 )
|
public final void encodeBit( boolean value )
|
||||||
{
|
{
|
||||||
if ( bm == 0x100 )
|
if ( bm == 0x100 )
|
||||||
|
@ -65,13 +82,14 @@ public class BitCoderContext
|
||||||
|
|
||||||
public final boolean decodeBit()
|
public final boolean decodeBit()
|
||||||
{
|
{
|
||||||
if ( bm == 0x100 )
|
if ( bits == 0 )
|
||||||
{
|
{
|
||||||
bm = 1;
|
bits = 8;
|
||||||
b = ab[++idx];
|
b = ab[++idx] & 0xff;
|
||||||
}
|
}
|
||||||
boolean value = ( ( b & bm ) != 0 );
|
boolean value = ( ( b & 1 ) != 0 );
|
||||||
bm <<= 1;
|
b >>>= 1;
|
||||||
|
bits--;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,19 +129,46 @@ public class BitCoderContext
|
||||||
int im = 1; // integer mask
|
int im = 1; // integer mask
|
||||||
while (( value | im ) <= max)
|
while (( value | im ) <= max)
|
||||||
{
|
{
|
||||||
if ( bm == 0x100 )
|
if ( bits == 0 )
|
||||||
{
|
{
|
||||||
bm = 1;
|
bits = 8;
|
||||||
b = ab[++idx];
|
b = ab[++idx] & 0xff;
|
||||||
}
|
}
|
||||||
if ( ( b & bm ) != 0 )
|
if ( ( b & 1 ) != 0 )
|
||||||
value |= im;
|
value |= im;
|
||||||
bm <<= 1;
|
b >>>= 1;
|
||||||
|
bits--;
|
||||||
im <<= 1;
|
im <<= 1;
|
||||||
}
|
}
|
||||||
return value;
|
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
|
* @return the encoded length in bytes
|
||||||
*/
|
*/
|
||||||
|
@ -135,7 +180,7 @@ public class BitCoderContext
|
||||||
/**
|
/**
|
||||||
* @return the encoded length in bits
|
* @return the encoded length in bits
|
||||||
*/
|
*/
|
||||||
public final long getBitPosition()
|
public final long getWritingBitPosition()
|
||||||
{
|
{
|
||||||
long bitpos = idx << 3;
|
long bitpos = idx << 3;
|
||||||
int m = bm;
|
int m = bm;
|
||||||
|
@ -147,4 +192,53 @@ public class BitCoderContext
|
||||||
return bitpos;
|
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;
|
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;
|
int end = ab.length;
|
||||||
for( int j=0; j<end; j++ )
|
for( int j=0; j<end; j++ )
|
||||||
{
|
{
|
||||||
byte b = ab[j];
|
crc = (crc >>> 8) ^ crctable[(crc ^ ab[j]) & 0xff];
|
||||||
if ( j == inverseBitByteIndex ) b ^= 1;
|
|
||||||
crc = (crc >>> 8) ^ crctable[(crc ^ b) & 0xff];
|
|
||||||
}
|
}
|
||||||
return crc;
|
return isInverse ? crc | 0x80000000 : crc & 0x7fffffff; // ... and set as high bit
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] crctable = {
|
private static int[] crctable = {
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class BitCoderContextTest
|
||||||
for ( int i = 0; i < 1000; i++ )
|
for ( int i = 0; i < 1000; i++ )
|
||||||
{
|
{
|
||||||
int value = ctx.decodeVarBits();
|
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