more re-use after timeout

This commit is contained in:
Arndt 2015-10-25 13:39:23 +01:00
parent 723cf90dd2
commit 14a18fd770
6 changed files with 301 additions and 163 deletions

View file

@ -31,6 +31,7 @@ public final class OsmTrack
public MatchedWaypoint endPoint; public MatchedWaypoint endPoint;
public long[] nogoChecksums; public long[] nogoChecksums;
public boolean isDirty;
private static class OsmPathElementHolder private static class OsmPathElementHolder
{ {
@ -38,7 +39,6 @@ public final class OsmTrack
public OsmPathElementHolder nextHolder; public OsmPathElementHolder nextHolder;
} }
public ArrayList<OsmPathElement> nodes = new ArrayList<OsmPathElement>(); public ArrayList<OsmPathElement> nodes = new ArrayList<OsmPathElement>();
private CompactLongMap<OsmPathElementHolder> nodesMap; private CompactLongMap<OsmPathElementHolder> nodesMap;
@ -56,7 +56,7 @@ public final class OsmTrack
public void buildMap() public void buildMap()
{ {
nodesMap = new CompactLongMap<OsmPathElementHolder>(); nodesMap = new CompactLongMap<OsmPathElementHolder>();
for( OsmPathElement node: nodes ) for ( OsmPathElement node : nodes )
{ {
long id = node.getIdFromPos(); long id = node.getIdFromPos();
OsmPathElementHolder nh = new OsmPathElementHolder(); OsmPathElementHolder nh = new OsmPathElementHolder();
@ -64,7 +64,7 @@ public final class OsmTrack
OsmPathElementHolder h = nodesMap.get( id ); OsmPathElementHolder h = nodesMap.get( id );
if ( h != null ) if ( h != null )
{ {
while( h.nextHolder != null ) while (h.nextHolder != null)
{ {
h = h.nextHolder; h = h.nextHolder;
} }
@ -82,7 +82,7 @@ public final class OsmTrack
{ {
ArrayList<String> res = new ArrayList<String>(); ArrayList<String> res = new ArrayList<String>();
MessageData current = null; MessageData current = null;
for( OsmPathElement n : nodes ) for ( OsmPathElement n : nodes )
{ {
if ( n.message != null ) if ( n.message != null )
{ {
@ -110,7 +110,9 @@ public final class OsmTrack
/** /**
* writes the track in binary-format to a file * writes the track in binary-format to a file
* @param filename the filename to write to *
* @param filename
* the filename to write to
*/ */
public void writeBinary( String filename ) throws Exception public void writeBinary( String filename ) throws Exception
{ {
@ -118,13 +120,14 @@ public final class OsmTrack
endPoint.writeToStream( dos ); endPoint.writeToStream( dos );
dos.writeInt( nodes.size() ); dos.writeInt( nodes.size() );
for( OsmPathElement node: nodes ) for ( OsmPathElement node : nodes )
{ {
node.writeToStream( dos ); node.writeToStream( dos );
} }
dos.writeLong( nogoChecksums[0] ); dos.writeLong( nogoChecksums[0] );
dos.writeLong( nogoChecksums[1] ); dos.writeLong( nogoChecksums[1] );
dos.writeLong( nogoChecksums[2] ); dos.writeLong( nogoChecksums[2] );
dos.writeBoolean( isDirty );
dos.close(); dos.close();
} }
@ -148,7 +151,7 @@ public final class OsmTrack
t.endPoint = ep; t.endPoint = ep;
int n = dis.readInt(); int n = dis.readInt();
OsmPathElement last_pe = null; OsmPathElement last_pe = null;
for( int i=0; i<n; i++ ) for ( int i = 0; i < n; i++ )
{ {
OsmPathElement pe = OsmPathElement.readFromStream( dis ); OsmPathElement pe = OsmPathElement.readFromStream( dis );
pe.origin = last_pe; pe.origin = last_pe;
@ -164,14 +167,21 @@ public final class OsmTrack
al[0] = dis.readLong(); al[0] = dis.readLong();
al[1] = dis.readLong(); al[1] = dis.readLong();
al[2] = dis.readLong(); al[2] = dis.readLong();
} catch( EOFException eof ) { /* kind of expected */ } }
catch (EOFException eof) { /* kind of expected */ }
try
{
boolean isDirty = dis.readBoolean();
if ( t != null ) t.isDirty = isDirty;
}
catch (EOFException eof) { /* kind of expected */ }
dis.close(); dis.close();
boolean nogoCheckOk = Math.abs( al[0] - nogoChecksums[0] ) <= 20 boolean nogoCheckOk = Math.abs( al[0] - nogoChecksums[0] ) <= 20
&& Math.abs( al[1] - nogoChecksums[1] ) <= 20 && Math.abs( al[1] - nogoChecksums[1] ) <= 20
&& Math.abs( al[2] - nogoChecksums[2] ) <= 20; && Math.abs( al[2] - nogoChecksums[2] ) <= 20;
if ( !nogoCheckOk ) return null; if ( !nogoCheckOk ) return null;
} }
catch( Exception e ) catch (Exception e)
{ {
throw new RuntimeException( "Exception reading rawTrack: " + e ); throw new RuntimeException( "Exception reading rawTrack: " + e );
} }
@ -182,7 +192,8 @@ public final class OsmTrack
public void addNodes( OsmTrack t ) public void addNodes( OsmTrack t )
{ {
for( OsmPathElement n : t.nodes ) addNode( n ); for ( OsmPathElement n : t.nodes )
addNode( n );
buildMap(); buildMap();
} }
@ -194,7 +205,7 @@ public final class OsmTrack
public OsmPathElement getLink( long n1, long n2 ) public OsmPathElement getLink( long n1, long n2 )
{ {
OsmPathElementHolder h = nodesMap.get( n2 ); OsmPathElementHolder h = nodesMap.get( n2 );
while( h != null ) while (h != null)
{ {
OsmPathElement e1 = h.node.origin; OsmPathElement e1 = h.node.origin;
if ( e1 != null && e1.getIdFromPos() == n1 ) if ( e1 != null && e1.getIdFromPos() == n1 )
@ -208,11 +219,11 @@ public final class OsmTrack
public void appendTrack( OsmTrack t ) public void appendTrack( OsmTrack t )
{ {
for( int i=0; i<t.nodes.size(); i++ ) for ( int i = 0; i < t.nodes.size(); i++ )
{ {
if ( i > 0 || nodes.size() == 0 ) if ( i > 0 || nodes.size() == 0 )
{ {
nodes.add( t.nodes.get(i) ); nodes.add( t.nodes.get( i ) );
} }
} }
distance += t.distance; distance += t.distance;
@ -228,7 +239,9 @@ public final class OsmTrack
/** /**
* writes the track in gpx-format to a file * writes the track in gpx-format to a file
* @param filename the filename to write to *
* @param filename
* the filename to write to
*/ */
public void writeGpx( String filename ) throws Exception public void writeGpx( String filename ) throws Exception
{ {
@ -240,14 +253,16 @@ public final class OsmTrack
public String formatAsGpx() public String formatAsGpx()
{ {
StringBuilder sb = new StringBuilder(8192); StringBuilder sb = new StringBuilder( 8192 );
sb.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); sb.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
for( int i=messageList.size()-1; i >= 0; i-- ) for ( int i = messageList.size() - 1; i >= 0; i-- )
{ {
String message = messageList.get(i); String message = messageList.get( i );
if ( i < messageList.size()-1 ) message = "(alt-index " + i + ": " + message + " )"; if ( i < messageList.size() - 1 )
if ( message != null ) sb.append("<!-- ").append(message).append(" -->\n"); message = "(alt-index " + i + ": " + message + " )";
if ( message != null )
sb.append( "<!-- " ).append( message ).append( " -->\n" );
} }
sb.append( "<gpx \n" ); sb.append( "<gpx \n" );
sb.append( " xmlns=\"http://www.topografix.com/GPX/1/1\" \n" ); sb.append( " xmlns=\"http://www.topografix.com/GPX/1/1\" \n" );
@ -255,13 +270,14 @@ public final class OsmTrack
sb.append( " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" \n" ); sb.append( " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" \n" );
sb.append( " creator=\"BRouter-1.3.1\" version=\"1.1\">\n" ); sb.append( " creator=\"BRouter-1.3.1\" version=\"1.1\">\n" );
sb.append( " <trk>\n" ); sb.append( " <trk>\n" );
sb.append(" <name>").append(name).append("</name>\n"); sb.append( " <name>" ).append( name ).append( "</name>\n" );
sb.append( " <trkseg>\n" ); sb.append( " <trkseg>\n" );
for( OsmPathElement n : nodes ) for ( OsmPathElement n : nodes )
{ {
String sele = n.getSElev() == Short.MIN_VALUE ? "" : "<ele>" + n.getElev() + "</ele>"; String sele = n.getSElev() == Short.MIN_VALUE ? "" : "<ele>" + n.getElev() + "</ele>";
sb.append(" <trkpt lon=\"").append(formatPos(n.getILon() - 180000000)).append("\" lat=\"").append(formatPos(n.getILat() - 90000000)).append("\">").append(sele).append("</trkpt>\n"); sb.append( " <trkpt lon=\"" ).append( formatPos( n.getILon() - 180000000 ) ).append( "\" lat=\"" )
.append( formatPos( n.getILat() - 90000000 ) ).append( "\">" ).append( sele ).append( "</trkpt>\n" );
} }
sb.append( " </trkseg>\n" ); sb.append( " </trkseg>\n" );
@ -281,7 +297,7 @@ public final class OsmTrack
public String formatAsKml() public String formatAsKml()
{ {
StringBuilder sb = new StringBuilder(8192); StringBuilder sb = new StringBuilder( 8192 );
sb.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); sb.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
@ -304,10 +320,9 @@ public final class OsmTrack
sb.append( " <tessellate>1</tessellate>\n" ); sb.append( " <tessellate>1</tessellate>\n" );
sb.append( " <coordinates> " ); sb.append( " <coordinates> " );
for ( OsmPathElement n : nodes )
for( OsmPathElement n : nodes )
{ {
sb.append(formatPos(n.getILon() - 180000000)).append(",").append(formatPos(n.getILat() - 90000000)).append("\n"); sb.append( formatPos( n.getILon() - 180000000 ) ).append( "," ).append( formatPos( n.getILat() - 90000000 ) ).append( "\n" );
} }
sb.append( " </coordinates>\n" ); sb.append( " </coordinates>\n" );
@ -324,7 +339,7 @@ public final class OsmTrack
public String formatAsGeoJson() public String formatAsGeoJson()
{ {
StringBuilder sb = new StringBuilder(8192); StringBuilder sb = new StringBuilder( 8192 );
sb.append( "{\n" ); sb.append( "{\n" );
sb.append( " \"type\": \"FeatureCollection\",\n" ); sb.append( " \"type\": \"FeatureCollection\",\n" );
@ -339,10 +354,10 @@ public final class OsmTrack
sb.append( " \"plain-ascend\": \"" ).append( plainAscend ).append( "\",\n" ); sb.append( " \"plain-ascend\": \"" ).append( plainAscend ).append( "\",\n" );
sb.append( " \"cost\": \"" ).append( cost ).append( "\",\n" ); sb.append( " \"cost\": \"" ).append( cost ).append( "\",\n" );
sb.append( " \"messages\": [\n" ); sb.append( " \"messages\": [\n" );
sb.append( " [\"").append( MESSAGES_HEADER.replaceAll("\t", "\", \"") ).append( "\"],\n" ); sb.append( " [\"" ).append( MESSAGES_HEADER.replaceAll( "\t", "\", \"" ) ).append( "\"],\n" );
for( String m : aggregateMessages() ) for ( String m : aggregateMessages() )
{ {
sb.append( " [\"").append( m.replaceAll("\t", "\", \"") ).append( "\"],\n" ); sb.append( " [\"" ).append( m.replaceAll( "\t", "\", \"" ) ).append( "\"],\n" );
} }
sb.deleteCharAt( sb.lastIndexOf( "," ) ); sb.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( " ]\n" ); sb.append( " ]\n" );
@ -352,9 +367,9 @@ public final class OsmTrack
if ( iternity != null ) if ( iternity != null )
{ {
sb.append( " \"iternity\": [\n" ); sb.append( " \"iternity\": [\n" );
for( String s : iternity ) for ( String s : iternity )
{ {
sb.append( " \"").append( s ).append( "\",\n" ); sb.append( " \"" ).append( s ).append( "\",\n" );
} }
sb.deleteCharAt( sb.lastIndexOf( "," ) ); sb.deleteCharAt( sb.lastIndexOf( "," ) );
sb.append( " ],\n" ); sb.append( " ],\n" );
@ -363,10 +378,11 @@ public final class OsmTrack
sb.append( " \"type\": \"LineString\",\n" ); sb.append( " \"type\": \"LineString\",\n" );
sb.append( " \"coordinates\": [\n" ); sb.append( " \"coordinates\": [\n" );
for( OsmPathElement n : nodes ) for ( OsmPathElement n : nodes )
{ {
String sele = n.getSElev() == Short.MIN_VALUE ? "" : ", " + n.getElev(); String sele = n.getSElev() == Short.MIN_VALUE ? "" : ", " + n.getElev();
sb.append( " [" ).append(formatPos(n.getILon() - 180000000)).append(", ").append(formatPos(n.getILat() - 90000000)).append(sele).append( "],\n" ); sb.append( " [" ).append( formatPos( n.getILon() - 180000000 ) ).append( ", " ).append( formatPos( n.getILat() - 90000000 ) )
.append( sele ).append( "],\n" );
} }
sb.deleteCharAt( sb.lastIndexOf( "," ) ); sb.deleteCharAt( sb.lastIndexOf( "," ) );
@ -382,17 +398,20 @@ public final class OsmTrack
private static String formatPos( int p ) private static String formatPos( int p )
{ {
boolean negative = p < 0; boolean negative = p < 0;
if ( negative ) p = -p; if ( negative )
p = -p;
char[] ac = new char[12]; char[] ac = new char[12];
int i = 11; int i = 11;
while( p != 0 || i > 3 ) while (p != 0 || i > 3)
{ {
ac[i--] = (char)('0' + (p % 10)); ac[i--] = (char) ( '0' + ( p % 10 ) );
p /= 10; p /= 10;
if ( i == 5 ) ac[i--] = '.'; if ( i == 5 )
ac[i--] = '.';
} }
if ( negative ) ac[i--] = '-'; if ( negative )
return new String( ac, i+1, 11-i ); ac[i--] = '-';
return new String( ac, i + 1, 11 - i );
} }
public void dumpMessages( String filename, RoutingContext rc ) throws Exception public void dumpMessages( String filename, RoutingContext rc ) throws Exception
@ -404,14 +423,15 @@ public final class OsmTrack
public void writeMessages( BufferedWriter bw, RoutingContext rc ) throws Exception public void writeMessages( BufferedWriter bw, RoutingContext rc ) throws Exception
{ {
dumpLine( bw, MESSAGES_HEADER ); dumpLine( bw, MESSAGES_HEADER );
for( String m : aggregateMessages() ) for ( String m : aggregateMessages() )
{ {
dumpLine( bw, m ); dumpLine( bw, m );
} }
if ( bw != null ) bw.close(); if ( bw != null )
bw.close();
} }
private void dumpLine( BufferedWriter bw, String s) throws Exception private void dumpLine( BufferedWriter bw, String s ) throws Exception
{ {
if ( bw == null ) if ( bw == null )
{ {
@ -427,28 +447,29 @@ public final class OsmTrack
public void readGpx( String filename ) throws Exception public void readGpx( String filename ) throws Exception
{ {
File f = new File( filename ); File f = new File( filename );
if ( !f.exists() ) return; if ( !f.exists() )
BufferedReader br = new BufferedReader( return;
new InputStreamReader( BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream( f ) ) );
new FileInputStream( f ) ) );
for(;;) for ( ;; )
{ {
String line = br.readLine(); String line = br.readLine();
if ( line == null ) break; if ( line == null )
break;
int idx0 = line.indexOf( "<trkpt lon=\"" ); int idx0 = line.indexOf( "<trkpt lon=\"" );
if ( idx0 >= 0 ) if ( idx0 >= 0 )
{ {
idx0 += 12; idx0 += 12;
int idx1 = line.indexOf( '"', idx0 ); int idx1 = line.indexOf( '"', idx0 );
int ilon = (int)((Double.parseDouble( line.substring( idx0, idx1 ) ) + 180. )*1000000. + 0.5); int ilon = (int) ( ( Double.parseDouble( line.substring( idx0, idx1 ) ) + 180. ) * 1000000. + 0.5 );
int idx2 = line.indexOf( " lat=\"" ); int idx2 = line.indexOf( " lat=\"" );
if ( idx2 < 0 ) continue; if ( idx2 < 0 )
continue;
idx2 += 6; idx2 += 6;
int idx3 = line.indexOf( '"', idx2 ); int idx3 = line.indexOf( '"', idx2 );
int ilat = (int)((Double.parseDouble( line.substring( idx2, idx3 ) ) + 90. )*1000000. + 0.5); int ilat = (int) ( ( Double.parseDouble( line.substring( idx2, idx3 ) ) + 90. ) * 1000000. + 0.5 );
nodes.add( OsmPathElement.create( ilon, ilat, (short)0, null, false ) ); nodes.add( OsmPathElement.create( ilon, ilat, (short) 0, null, false ) );
} }
} }
br.close(); br.close();
@ -456,12 +477,14 @@ public final class OsmTrack
public boolean equalsTrack( OsmTrack t ) public boolean equalsTrack( OsmTrack t )
{ {
if ( nodes.size() != t.nodes.size() ) return false; if ( nodes.size() != t.nodes.size() )
for( int i=0; i<nodes.size(); i++ ) return false;
for ( int i = 0; i < nodes.size(); i++ )
{ {
OsmPathElement e1 = nodes.get(i); OsmPathElement e1 = nodes.get( i );
OsmPathElement e2 = t.nodes.get(i); OsmPathElement e2 = t.nodes.get( i );
if ( e1.getILon() != e2.getILon() || e1.getILat() != e2.getILat() ) return false; if ( e1.getILon() != e2.getILon() || e1.getILat() != e2.getILat() )
return false;
} }
return true; return true;
} }

View file

@ -0,0 +1,98 @@
/**
* Container for routig configs
*
* @author ab
*/
package btools.router;
import java.io.File;
import btools.expressions.BExpressionContextGlobal;
import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay;
import btools.expressions.BExpressionMetaData;
public final class ProfileCache
{
private static BExpressionContextWay expctxWay;
private static BExpressionContextNode expctxNode;
private static File lastLookupFile;
private static File lastProfileFile;
private static long lastLookupTimestamp;
private static long lastProfileTimestamp;
private static boolean profilesBusy;
public static synchronized boolean parseProfile( RoutingContext rc )
{
String profileBaseDir = System.getProperty( "profileBaseDir" );
File profileDir;
File profileFile;
if ( profileBaseDir == null )
{
profileDir = new File( rc.localFunction ).getParentFile();
profileFile = new File( rc.localFunction ) ;
}
else
{
profileDir = new File( profileBaseDir );
profileFile = new File( profileDir, rc.localFunction + ".brf" ) ;
}
File lookupFile = new File( profileDir, "lookups.dat" );
// check for re-use
if ( expctxWay != null && expctxNode != null && !profilesBusy )
{
if ( profileFile.equals( lastProfileFile ) && lookupFile.equals( lastLookupFile ) )
{
if ( profileFile.lastModified() == lastProfileTimestamp
&& lookupFile.lastModified() == lastLookupTimestamp )
{
rc.expctxWay = expctxWay;
rc.expctxNode = expctxNode;
profilesBusy = true;
rc.readGlobalConfig(expctxWay);
return true;
}
}
}
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 );
meta.readMetaData( new File( profileDir, "lookups.dat" ) );
expctxGlobal.parseFile( profileFile, null );
expctxGlobal.evaluate( new int[0] );
rc.readGlobalConfig(expctxGlobal);
rc.expctxWay.parseFile( profileFile, "global" );
rc.expctxNode.parseFile( profileFile, "global" );
lastProfileTimestamp = profileFile.lastModified();
lastLookupTimestamp = lookupFile.lastModified();
lastProfileFile = profileFile;
lastLookupFile = lookupFile;
expctxWay = rc.expctxWay;
expctxNode = rc.expctxNode;
profilesBusy = true;
return false;
}
public static synchronized void releaseProfile( RoutingContext rc )
{
// only the thread that holds the cached instance can release it
if ( rc.expctxWay == expctxWay && rc.expctxNode == expctxNode )
{
profilesBusy = false;
}
rc.expctxWay = null;
rc.expctxNode = null;
}
}

View file

@ -10,10 +10,6 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import btools.expressions.BExpressionContextGlobal;
import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay;
import btools.expressions.BExpressionMetaData;
import btools.mapaccess.NodesCache; import btools.mapaccess.NodesCache;
import btools.mapaccess.OsmLink; import btools.mapaccess.OsmLink;
import btools.mapaccess.OsmLinkHolder; import btools.mapaccess.OsmLinkHolder;
@ -42,7 +38,6 @@ public class RoutingEngine extends Thread
private volatile boolean terminated; private volatile boolean terminated;
protected File profileDir;
protected String segmentDir; protected String segmentDir;
private String outfileBase; private String outfileBase;
private String logfileBase; private String logfileBase;
@ -71,36 +66,30 @@ public class RoutingEngine extends Thread
this.infoLogEnabled = outfileBase != null; this.infoLogEnabled = outfileBase != null;
this.routingContext = rc; this.routingContext = rc;
if ( rc.localFunction != null ) try
{ {
String profileBaseDir = System.getProperty( "profileBaseDir" ); File debugLog = new File( new File( routingContext.localFunction ).getParentFile(), "../debug.txt" );
File profileFile; if ( debugLog.exists() )
if ( profileBaseDir == null )
{ {
profileDir = new File( rc.localFunction ).getParentFile(); infoLogWriter = new FileWriter( debugLog, true );
profileFile = new File( rc.localFunction ) ; logInfo( "********** start request at " );
logInfo( "********** " + new Date() );
} }
else }
catch( IOException ioe )
{ {
profileDir = new File( profileBaseDir ); throw new RuntimeException( "cannot open debug-log:" + ioe );
profileFile = new File( profileDir, rc.localFunction + ".brf" ) ; }
boolean cachedProfile = ProfileCache.parseProfile( rc );
if ( hasInfo() )
{
logInfo( "parsed profile " + rc.localFunction + " cached=" + cachedProfile );
}
} }
BExpressionMetaData meta = new BExpressionMetaData(); private boolean hasInfo()
{
BExpressionContextGlobal expctxGlobal = new BExpressionContextGlobal( meta ); return infoLogEnabled || infoLogWriter != null;
rc.expctxWay = new BExpressionContextWay( rc.serversizing ? 262144 : 8192, meta );
rc.expctxNode = new BExpressionContextNode( rc.serversizing ? 16384 : 2048, meta );
meta.readMetaData( new File( profileDir, "lookups.dat" ) );
expctxGlobal.parseFile( profileFile, null );
expctxGlobal.evaluate( new int[0] );
rc.readGlobalConfig(expctxGlobal);
rc.expctxWay.parseFile( profileFile, "global" );
rc.expctxNode.parseFile( profileFile, "global" );
}
} }
private void logInfo( String s ) private void logInfo( String s )
@ -141,13 +130,6 @@ public class RoutingEngine extends Thread
{ {
try try
{ {
File debugLog = new File( profileDir, "../debug.txt" );
if ( debugLog.exists() )
{
infoLogWriter = new FileWriter( debugLog, true );
logInfo( "start request at " + new Date() );
}
// delete nogos with waypoints in them // delete nogos with waypoints in them
routingContext.cleanNogolist( waypoints ); routingContext.cleanNogolist( waypoints );
@ -232,6 +214,8 @@ public class RoutingEngine extends Thread
} }
finally finally
{ {
ProfileCache.releaseProfile( routingContext );
if ( nodesCache != null ) if ( nodesCache != null )
{ {
nodesCache.close(); nodesCache.close();
@ -313,6 +297,10 @@ public class RoutingEngine extends Thread
nearbyTrack = OsmTrack.readBinary( routingContext.rawTrackPath, waypoints.get( waypoints.size()-1), routingContext.getNogoChecksums() ); nearbyTrack = OsmTrack.readBinary( routingContext.rawTrackPath, waypoints.get( waypoints.size()-1), routingContext.getNogoChecksums() );
if ( nearbyTrack != null ) if ( nearbyTrack != null )
{ {
if ( hasInfo() )
{
logInfo( "read referenceTrack, dirty=" + nearbyTrack.isDirty );
}
nUnmatched--; nUnmatched--;
} }
} }
@ -506,6 +494,7 @@ public class RoutingEngine extends Thread
OsmTrack track = null; OsmTrack track = null;
double[] airDistanceCostFactors = new double[]{ routingContext.pass1coefficient, routingContext.pass2coefficient }; double[] airDistanceCostFactors = new double[]{ routingContext.pass1coefficient, routingContext.pass2coefficient };
boolean isDirty = false; boolean isDirty = false;
IllegalArgumentException dirtyMessage = null;
if ( nearbyTrack != null ) if ( nearbyTrack != null )
{ {
@ -524,6 +513,7 @@ public class RoutingEngine extends Thread
{ {
track = mergeTrack( matchPath, nearbyTrack ); track = mergeTrack( matchPath, nearbyTrack );
isDirty = true; isDirty = true;
dirtyMessage = iae;
logInfo( "using fast partial recalc" ); logInfo( "using fast partial recalc" );
} }
maxRunningTime += System.currentTimeMillis() - startTime; // reset timeout... maxRunningTime += System.currentTimeMillis() - startTime; // reset timeout...
@ -541,7 +531,24 @@ public class RoutingEngine extends Thread
continue; continue;
} }
OsmTrack t = findTrack( cfi == 0 ? "pass0" : "pass1", startWp, endWp, track , refTrack, false ); OsmTrack t;
try
{
t = findTrack( cfi == 0 ? "pass0" : "pass1", startWp, endWp, track , refTrack, false );
}
catch( IllegalArgumentException iae )
{
if ( !terminated && matchPath != null ) // timeout, but eventually prepare a dirty ref track
{
logInfo( "supplying dirty reference track after timeout" );
foundRawTrack = mergeTrack( matchPath, track );
foundRawTrack.endPoint = endWp;
foundRawTrack.nogoChecksums = routingContext.getNogoChecksums();
foundRawTrack.isDirty = true;
}
throw iae;
}
if ( t == null && track != null && matchPath != null ) if ( t == null && track != null && matchPath != null )
{ {
// ups, didn't find it, use a merge // ups, didn't find it, use a merge
@ -560,17 +567,25 @@ public class RoutingEngine extends Thread
} }
if ( track == null ) throw new IllegalArgumentException( "no track found" ); if ( track == null ) throw new IllegalArgumentException( "no track found" );
if ( refTrack == null && !isDirty ) boolean wasClean = nearbyTrack != null && !nearbyTrack.isDirty;
if ( refTrack == null && !(wasClean && isDirty) ) // do not overwrite a clean with a dirty track
{ {
logInfo( "supplying new reference track" ); logInfo( "supplying new reference track, dirty=" + isDirty );
track.endPoint = endWp; track.endPoint = endWp;
track.nogoChecksums = routingContext.getNogoChecksums(); track.nogoChecksums = routingContext.getNogoChecksums();
track.isDirty = isDirty;
foundRawTrack = track; foundRawTrack = track;
} }
if ( !wasClean && isDirty )
{
throw dirtyMessage;
}
// final run for verbose log info and detail nodes // final run for verbose log info and detail nodes
airDistanceCostFactor = 0.; airDistanceCostFactor = 0.;
guideTrack = track; guideTrack = track;
startTime = System.currentTimeMillis(); // reset timeout...
try try
{ {
OsmTrack tt = findTrack( "re-tracking", startWp, endWp, null , refTrack, false ); OsmTrack tt = findTrack( "re-tracking", startWp, endWp, null , refTrack, false );
@ -804,7 +819,8 @@ public class RoutingEngine extends Thread
continue; continue;
} }
if ( matchPath != null && fastPartialRecalc && firstMatchCost < 500 && path.cost > 30L*firstMatchCost ) if ( matchPath != null && fastPartialRecalc && firstMatchCost < 500 && path.cost > 30L*firstMatchCost
&& !costCuttingTrack.isDirty )
{ {
logInfo( "early exit: firstMatchCost=" + firstMatchCost + " path.cost=" + path.cost ); logInfo( "early exit: firstMatchCost=" + firstMatchCost + " path.cost=" + path.cost );
throw new IllegalArgumentException( "early exit for a close recalc" ); throw new IllegalArgumentException( "early exit for a close recalc" );

View file

@ -194,7 +194,7 @@ public final class NodesCache
} }
catch (Exception e) catch (Exception e)
{ {
throw new RuntimeException( "error reading datafile " + currentFileName + ": ", e ); throw new RuntimeException( "error reading datafile " + currentFileName + ": " + e, e );
} }
} }

View file

@ -108,7 +108,7 @@ final public class PhysicalFile
if ( len < pos+extraLen ) // > is o.k. for future extensions! if ( len < pos+extraLen ) // > is o.k. for future extensions!
{ {
throw new IOException( "file of size " + len + " + too short, should be " + (pos+extraLen) ); throw new IOException( "file of size " + len + " too short, should be " + (pos+extraLen) );
} }
ra.seek( pos ); ra.seek( pos );

View file

@ -52,12 +52,9 @@ public class BRouterWorker
RoutingEngine cr = new RoutingEngine( null, null, segmentDir, readPositions(params), rc ); RoutingEngine cr = new RoutingEngine( null, null, segmentDir, readPositions(params), rc );
cr.quite = true; cr.quite = true;
cr.doRun( maxRunningTime ); cr.doRun( maxRunningTime );
if ( cr.getErrorMessage() != null )
{
return cr.getErrorMessage();
}
// store new reference track if any // store new reference track if any
// (can exist fot timeed-out search)
if ( cr.getFoundRawTrack() != null ) if ( cr.getFoundRawTrack() != null )
{ {
try try
@ -67,6 +64,10 @@ public class BRouterWorker
catch( Exception e ) {} catch( Exception e ) {}
} }
if ( cr.getErrorMessage() != null )
{
return cr.getErrorMessage();
}
String format = params.getString("trackFormat"); String format = params.getString("trackFormat");
boolean writeKml = format != null && "kml".equals( format ); boolean writeKml = format != null && "kml".equals( format );