map access layer cleanup

This commit is contained in:
Arndt 2015-09-12 16:12:24 +02:00
parent 2cec35f3cc
commit f8dee5b7d1
7 changed files with 163 additions and 150 deletions

View file

@ -109,7 +109,7 @@ final class OsmPath implements OsmLinkHolder
private void addAddionalPenalty(OsmTrack refTrack, boolean detailMode, OsmPath origin, OsmLink link, RoutingContext rc )
{
if ( link.descriptionBitmap == null ) throw new IllegalArgumentException( "null description for class: " + link.getClass() );
if ( link.descriptionBitmap == null ) throw new IllegalArgumentException( "null description for: " + link );
boolean recordTransferNodes = detailMode || rc.countTraffic;
boolean recordMessageData = detailMode;

View file

@ -381,7 +381,7 @@ public class RoutingEngine extends Thread
{
continue;
}
expandHollowLinkTargets( n, false );
expandHollowLinkTargets( n );
OsmLink startLink = new OsmLink();
startLink.targetNode = n;
OsmPath startPath = new OsmPath( startLink );
@ -418,30 +418,12 @@ public class RoutingEngine extends Thread
}
// expand hollow link targets and resolve reverse links
private void expandHollowLinkTargets( OsmNode n, boolean failOnReverseNotFound )
private void expandHollowLinkTargets( OsmNode n )
{
for( OsmLink link = n.firstlink; link != null; link = link.next )
{
if ( ! nodesCache.obtainNonHollowNode( link.targetNode ) )
{
continue;
nodesCache.obtainNonHollowNode( link.targetNode );
}
if ( link.counterLinkWritten )
{
OsmLink rlink = link.targetNode.getReverseLink( n.getILon(), n.getILat() );
if ( rlink == null )
{
if ( failOnReverseNotFound ) throw new RuntimeException( "reverse link not found!" );
}
else
{
link.descriptionBitmap = rlink.descriptionBitmap;
link.firsttransferBytes = rlink.firsttransferBytes;
}
}
}
n.wasProcessed = true;
}
private OsmTrack searchTrack( MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack )
@ -541,7 +523,7 @@ public class RoutingEngine extends Thread
{
return null;
}
expandHollowLinkTargets( start, true );
expandHollowLinkTargets( start );
return start;
}
@ -804,10 +786,7 @@ public class RoutingEngine extends Thread
continue;
}
if ( !currentNode.wasProcessed )
{
expandHollowLinkTargets( currentNode, true );
}
expandHollowLinkTargets( currentNode );
if ( sourceNode != null )
{

View file

@ -26,6 +26,7 @@ public final class BExpressionMetaData
private static final String CONTEXT_TAG = "---context:";
private static final String VERSION_TAG = "---lookupversion:";
private static final String MINOR_VERSION_TAG = "---minorversion:";
private static final String VARLENGTH_TAG = "---readvarlength";
public short lookupVersion = -1;
public short lookupMinorVersion = -1;
@ -66,6 +67,10 @@ public final class BExpressionMetaData
lookupMinorVersion = Short.parseShort( line.substring( MINOR_VERSION_TAG.length() ) );
continue;
}
if ( line.startsWith( VARLENGTH_TAG ) ) // tag removed...
{
continue;
}
if ( ctx != null ) ctx.parseMetaLine( line );
}
br.close();

View file

@ -14,7 +14,7 @@ import btools.util.Crc32;
final class MicroCache extends ByteDataReader
{
private long[] faid;
private int[] faid;
private int[] fapos;
private int size = 0;
private int delcount = 0;
@ -24,6 +24,9 @@ final class MicroCache extends ByteDataReader
// the object parsing position and length
private int aboffsetEnd;
private int lonIdxBase;
private int latIdxBase;
// cache control: a virgin cache can be
// put to ghost state for later recovery
boolean virgin = true;
@ -35,8 +38,8 @@ final class MicroCache extends ByteDataReader
int lonDegree = lonIdx80/80;
int latDegree = latIdx80/80;
int lonIdxBase = (lonIdx80/5)*62500 + 31250;
int latIdxBase = (latIdx80/5)*62500 + 31250;
lonIdxBase = (lonIdx80/5)*62500 + 31250;
latIdxBase = (latIdx80/5)*62500 + 31250;
int subIdx = (latIdx80-80*latDegree)*80 + (lonIdx80-80*lonDegree);
@ -61,8 +64,7 @@ final class MicroCache extends ByteDataReader
int nbytes = 0;
for(int i = 0; i<size; i++)
{
int ilon = readShort();
int ilat = readShort();
aboffset += 4;
int bodySize = readVarLengthUnsigned();
aboffset += bodySize;
@ -79,20 +81,15 @@ final class MicroCache extends ByteDataReader
byte[] nab = new byte[nbytes];
aboffset = 4;
int noffset = 0;
faid = new long[size];
faid = new int[size];
fapos = new int[size];
p2size = 0x40000000;
while( p2size > size ) p2size >>= 1;
for(int i = 0; i<size; i++)
{
int ilon = readShort();
int ilat = readShort();
ilon += lonIdxBase;
ilat += latIdxBase;
long nodeId = ((long)ilon)<<32 | ilat;
faid[i] = readInt() ^ 0x8000; // flip lat-sign for correct ordering
faid[i] = nodeId;
int bodySize = readVarLengthUnsigned();
fapos[i] = noffset;
System.arraycopy( ab, aboffset, nab, noffset, bodySize );
@ -123,13 +120,14 @@ final class MicroCache extends ByteDataReader
* Throws an exception if that id was already requested
* as an early detector for identity problems
*/
private boolean getAndClear( long id )
private boolean getAndClear( long id64 )
{
if ( size == 0 )
{
return false;
}
long[] a = faid;
int id = shrinkId( id64 );
int[] a = faid;
int offset = p2size;
int n = 0;
@ -194,7 +192,7 @@ final class MicroCache extends ByteDataReader
}
else
{
long[] nfaid = new long[nsize];
int[] nfaid = new int[nsize];
int[] nfapos = new int[nsize];
int idx = 0;
@ -242,14 +240,30 @@ final class MicroCache extends ByteDataReader
for( int i=0; i<size; i++ )
{
OsmNode n = new OsmNode( faid[i] );
int id32 = faid[i];
long id64 = expandId( id32 );
OsmNode n = new OsmNode( id64 );
n.setHollow();
nodesMap.put( faid[i], n );
nodesMap.put( n );
positions.add( n );
}
return positions;
}
private long expandId( int id32 )
{
int lon32 = lonIdxBase + (short)(id32 >> 16);
int lat32 = latIdxBase + (short)((id32 & 0xffff) ^ 0x8000);
return ((long)lon32)<<32 | lat32;
}
private int shrinkId( long id64 )
{
int lon32 = (int)(id64 >> 32);
int lat32 = (int)(id64 & 0xffffffff);
return (lon32 - lonIdxBase)<<16 | ( ( (lat32 - latIdxBase) & 0xffff) ^ 0x8000);
}
public boolean hasMoreData()
{
return aboffset < aboffsetEnd;

View file

@ -19,12 +19,6 @@ public class OsmLink
*/
public OsmNode targetNode;
/**
* The origin position
*/
public int ilatOrigin;
public int ilonOrigin;
public OsmLink next;
public byte[] firsttransferBytes;
@ -42,6 +36,8 @@ public class OsmLink
public boolean counterLinkWritten;
public byte state;
public OsmLinkHolder firstlinkholder = null;
final public void addLinkHolder( OsmLinkHolder holder )
@ -49,4 +45,9 @@ public class OsmLink
if ( firstlinkholder != null ) { holder.setNextForLink( firstlinkholder ); }
firstlinkholder = holder;
}
public String toString()
{
return "Link(target=" + targetNode.getIdFromPos() + " counterLinkWritten=" + counterLinkWritten + " state=" + state + ")";
}
}

View file

@ -81,15 +81,51 @@ public class OsmNode implements OsmPos
*/
public OsmLink firstlink = null;
public OsmLink firstreverse = null;
public boolean wasProcessed; // whether this node has all it's links resolved
// preliminry in forward order to avoid regressions
public void addLink( OsmLink link )
{
if ( firstlink != null ) link.next = firstlink;
if ( firstlink == null )
{
firstlink = link;
}
else
{
OsmLink l = firstlink;
while( l.next != null ) l = l.next;
l.next = link;
}
}
private OsmLink getCompatibleLink( int ilon, int ilat, boolean counterLinkWritten, int state )
{
for( OsmLink l = firstlink; l != null; l = l.next )
{
if ( counterLinkWritten == l.counterLinkWritten && l.state == state )
{
OsmNode t = l.targetNode;
if ( t.ilon == ilon && t.ilat == ilat )
{
l.state = 0;
return l;
}
}
}
// second try ignoring counterLinkWritten
// (border links are written in both directions)
for( OsmLink l = firstlink; l != null; l = l.next )
{
if ( l.state == state )
{
OsmNode t = l.targetNode;
if ( t.ilon == ilon && t.ilat == ilat )
{
l.state = 0;
return l;
}
}
}
return null;
}
public int calcDistance( OsmPos p )
{
@ -104,6 +140,10 @@ public class OsmNode implements OsmPos
return (int)(d + 1.0 );
}
public String toString()
{
return "" + getIdFromPos();
}
public void parseNodeBody( MicroCache is, OsmNodesMap hollowNodes, DistanceChecker dc )
{
@ -111,17 +151,12 @@ public class OsmNode implements OsmPos
selev = is.readShort();
OsmLink lastlink = null;
OsmLink firstHollowLink = firstlink;
firstlink = null;
while( is.hasMoreData() )
{
int ilonref = ilon;
int ilatref = ilat;
OsmLink link = new OsmLink();
boolean counterLinkWritten = false;
OsmTransferNode firstTransferNode = null;
OsmTransferNode lastTransferNode = null;
int linklon;
@ -163,10 +198,10 @@ public class OsmNode implements OsmPos
}
if ( (bitField & SKIPDETAILS_BITMASK ) != 0 )
{
link.counterLinkWritten = true;
counterLinkWritten = true;
}
if ( description == null && !link.counterLinkWritten ) throw new IllegalArgumentException( "internal error: missing way description!" );
if ( description == null && !counterLinkWritten ) throw new IllegalArgumentException( "internal error: missing way description!" );
boolean isTransfer = (bitField & TRANSFERNODE_BITMASK ) != 0;
if ( isTransfer )
@ -188,17 +223,16 @@ public class OsmNode implements OsmPos
}
else
{
link.descriptionBitmap = description;
break;
}
}
// performance shortcut: ignore link if out of reach
if ( dc != null && !link.counterLinkWritten )
if ( dc != null && !counterLinkWritten )
{
if ( !dc.isWithinRadius( ilon, ilat, firstTransferNode, linklon, linklat ) )
{
// continue;
continue;
}
}
@ -207,57 +241,46 @@ public class OsmNode implements OsmPos
continue; // skip self-ref
}
if ( lastlink == null )
{
firstlink = link;
}
else
{
lastlink.next = link;
}
lastlink = link;
OsmNode tn = null;
// first check the hollow links for that target
for( OsmLink l = firstHollowLink; l != null; l = l.next )
{
OsmNode t = l.targetNode;
if ( t.ilon == linklon && t.ilat == linklat )
{
tn = t;
break;
}
}
if ( tn == null ) // then check the hollow-nodes
// first check the known links for that target
OsmLink link = getCompatibleLink( linklon, linklat, counterLinkWritten, 2 );
if ( link == null ) // .. not found, then check the hollow nodes
{
long targetNodeId = ((long)linklon)<<32 | linklat;
tn = hollowNodes.get( targetNodeId ); // target node
OsmNode tn = hollowNodes.get( targetNodeId ); // target node
if ( tn == null ) // node not yet known, create a new hollow proxy
{
tn = new OsmNode(linklon, linklat);
tn.setHollow();
hollowNodes.put( targetNodeId, tn );
}
OsmLink hollowLink = new OsmLink();
hollowLink.targetNode = this;
tn.addLink( hollowLink ); // make us known at the hollow link
hollowNodes.put( tn );
}
link = new OsmLink();
link.targetNode = tn;
link.counterLinkWritten = counterLinkWritten;
link.state = 1;
addLink( link );
}
// now we have a link with a target node -> get the reverse link
OsmLink rlink = link.targetNode.getCompatibleLink( ilon, ilat, !counterLinkWritten, 1 );
if ( rlink == null ) // .. not found, create it
{
rlink = new OsmLink();
rlink.targetNode = this;
rlink.counterLinkWritten = !counterLinkWritten;
rlink.state = 2;
link.targetNode.addLink( rlink );
}
if ( !counterLinkWritten )
{
// we have the data for that link, so fill both the link ..
link.descriptionBitmap = description;
link.encodeFirsttransfer(firstTransferNode);
// compute the reverse link
if ( !link.counterLinkWritten )
// .. and the reverse
if ( rlink.counterLinkWritten )
{
OsmLink rlink = new OsmLink();
byte[] linkDescriptionBitmap = link.descriptionBitmap;
rlink.ilonOrigin = tn.ilon;
rlink.ilatOrigin = tn.ilat;
rlink.targetNode = this;
rlink.descriptionBitmap = linkDescriptionBitmap; // default for no transfer-nodes
rlink.descriptionBitmap = description; // default for no transfer-nodes
OsmTransferNode previous = null;
OsmTransferNode rtrans = null;
for( OsmTransferNode trans = firstTransferNode; trans != null; trans = trans.next )
@ -275,17 +298,18 @@ public class OsmNode implements OsmPos
rtrans.ilat = trans.ilat;
rtrans.selev = trans.selev;
rtrans.next = previous;
rtrans.descriptionBitmap = linkDescriptionBitmap;
rtrans.descriptionBitmap = description;
previous = rtrans;
}
rlink.encodeFirsttransfer(rtrans);
rlink.next = firstreverse;
firstreverse = rlink;
}
}
}
hollowNodes.remove( getIdFromPos() );
if ( dc == null )
{
hollowNodes.remove( this );
}
}
public boolean isHollow()
@ -320,34 +344,20 @@ public class OsmNode implements OsmPos
}
}
public OsmLink getReverseLink( int lon, int lat )
@Override
public boolean equals( Object o )
{
for( OsmLink rlink = firstreverse; rlink != null; rlink = rlink.next )
if ( o instanceof OsmNode )
{
if ( rlink.ilonOrigin == lon && rlink.ilatOrigin == lat )
{
unlinkRLink( rlink );
return rlink;
OsmNode n = (OsmNode)o;
return n.ilon == ilon && n.ilat == ilat;
}
}
return null;
return false;
}
public void unlinkRLink( OsmLink rlink )
@Override
public int hashCode( )
{
if ( rlink == firstreverse )
{
firstreverse = rlink.next;
return;
}
for( OsmLink l = firstreverse; l != null; l = l.next )
{
if ( l.next == rlink )
{
l.next = rlink.next;
return;
return ilon + ilat;
}
}
}
}

View file

@ -11,10 +11,12 @@ import btools.util.ByteArrayUnifier;
public final class OsmNodesMap
{
private HashMap<Long,OsmNode> hmap = new HashMap<Long,OsmNode>();
private HashMap<OsmNode,OsmNode> hmap = new HashMap<OsmNode,OsmNode>();
private ByteArrayUnifier abUnifier = new ByteArrayUnifier( 16384, false );
private OsmNode testKey = new OsmNode();
public ByteArrayUnifier getByteArrayUnifier()
{
return abUnifier;
@ -26,22 +28,24 @@ public final class OsmNodesMap
*/
public OsmNode get( long id )
{
return hmap.get( new Long( id ) );
testKey.ilon = (int)(id >> 32);
testKey.ilat = (int)(id & 0xffffffff);
return hmap.get( testKey );
}
public void remove( long id )
public void remove( OsmNode node )
{
hmap.remove( new Long( id ) );
hmap.remove( node );
}
/**
* Put a node into the map
* @return the previous node if that id existed, else null
*/
public OsmNode put( long id, OsmNode node )
public OsmNode put( OsmNode node )
{
return hmap.put( new Long( id ), node );
return hmap.put( node, node );
}