diff --git a/brouter-codec/src/main/java/btools/codec/MicroCache.java b/brouter-codec/src/main/java/btools/codec/MicroCache.java index 11d547e..3dde2ae 100644 --- a/brouter-codec/src/main/java/btools/codec/MicroCache.java +++ b/brouter-codec/src/main/java/btools/codec/MicroCache.java @@ -55,24 +55,24 @@ public class MicroCache extends ByteDataWriter p2size >>= 1; } - public void finishNode( long id ) + public final void finishNode( long id ) { fapos[size] = aboffset; faid[size] = shrinkId( id ); size++; } - public void discardNode() + public final void discardNode() { aboffset = startPos( size ); } - public int getSize() + public final int getSize() { return size; } - public int getDataSize() + public final int getDataSize() { return ab == null ? 0 : ab.length; } @@ -91,7 +91,7 @@ public class MicroCache extends ByteDataWriter * * @return true if id was found */ - public boolean getAndClear( long id64 ) + public final boolean getAndClear( long id64 ) { if ( size == 0 ) { @@ -130,12 +130,12 @@ public class MicroCache extends ByteDataWriter return false; } - protected int startPos( int n ) + protected final int startPos( int n ) { return n > 0 ? fapos[n - 1] & 0x7fffffff : 0; } - public void collect( int threshold ) + public final void collect( int threshold ) { if ( delcount > threshold ) { @@ -178,7 +178,7 @@ public class MicroCache extends ByteDataWriter } } - public void unGhost() + public final void unGhost() { ghost = false; delcount = 0; @@ -192,7 +192,7 @@ public class MicroCache extends ByteDataWriter /** * @return the 64-bit global id for the given cache-position */ - public long getIdForIndex( int i ) + public final long getIdForIndex( int i ) { int id32 = faid[i]; return expandId( id32 ); diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNodesMap.java b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNodesMap.java index 165d729..c62a7f5 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNodesMap.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNodesMap.java @@ -11,7 +11,7 @@ import btools.util.ByteArrayUnifier; public final class OsmNodesMap { - private HashMap hmap = new HashMap(); + private HashMap hmap = new HashMap(4096); private ByteArrayUnifier abUnifier = new ByteArrayUnifier( 16384, false ); diff --git a/brouter-util/src/main/java/btools/util/ByteDataReader.java b/brouter-util/src/main/java/btools/util/ByteDataReader.java index 857a9b2..8209c75 100644 --- a/brouter-util/src/main/java/btools/util/ByteDataReader.java +++ b/brouter-util/src/main/java/btools/util/ByteDataReader.java @@ -71,13 +71,13 @@ public class ByteDataReader * * @return the pointer to the first byte after that section */ - public int getEndPointer() + public final int getEndPointer() { int size = readVarLengthUnsigned(); return aboffset + size; } - public byte[] readDataUntil( int endPointer ) + public final byte[] readDataUntil( int endPointer ) { int size = endPointer - aboffset; if ( size == 0 ) @@ -89,7 +89,7 @@ public class ByteDataReader return data; } - public byte[] readVarBytes() + public final byte[] readVarBytes() { int len = readVarLengthUnsigned(); if ( len == 0 ) @@ -128,7 +128,7 @@ public class ByteDataReader aboffset += ta.length; } - public boolean hasMoreData() + public final boolean hasMoreData() { return aboffset < aboffsetEnd; } diff --git a/brouter-util/src/main/java/btools/util/SortedHeap.java b/brouter-util/src/main/java/btools/util/SortedHeap.java index b633db5..943d340 100644 --- a/brouter-util/src/main/java/btools/util/SortedHeap.java +++ b/brouter-util/src/main/java/btools/util/SortedHeap.java @@ -12,6 +12,11 @@ import java.util.Random; public final class SortedHeap { private int[][] al; + private int[] lv; // low values + + private int[] nextNonEmpty; + private int firstNonEmpty; + private int[] lp; // the low pointers private Object[][] vla; // value list array @@ -29,7 +34,7 @@ public final class SortedHeap /** * @return the lowest key value, or null if none */ - public V popLowestKeyValue() + public V popLowestKeyValue2() { int minId = 0; int minIdx = -1; @@ -53,14 +58,73 @@ public final class SortedHeap if ( minIdx == -1 ) return null; - int lp_minIdx = lp[minIdx]++; - Object[] vla_minIdx = vla[minIdx]; - V res = (V) vla_minIdx[lp_minIdx]; - vla_minIdx[lp_minIdx] = null; size--; - return res; + + return dropLowest( minIdx ); } + public V popLowestKeyValue() + { + int idx = firstNonEmpty; + if ( idx < 0 ) + { + return null; + } + size--; + int minId = lv[idx]; + int minIdx = idx; + for (;;) + { + idx = nextNonEmpty[idx]; + if ( idx < 0 ) + { + return dropLowest( minIdx ); + } + if ( lv[idx] < minId ) + { + minId = lv[idx]; + minIdx = idx; + } + } + } + + private V dropLowest( int idx ) + { + int lp_old = lp[idx]++; + int lp_new = lp_old+1; + if ( lp_new == 4 << idx ) + { + unlinkIdx( idx ); + } + else + { + lv[idx] = al[idx][lp_new]; + } + Object[] vlai = vla[idx]; + V res = (V) vlai[lp_old]; + vlai[lp_old] = null; + return res; + } + + private void unlinkIdx( int idx ) + { + if ( idx == firstNonEmpty ) + { + firstNonEmpty = nextNonEmpty[idx]; + return; + } + int i = firstNonEmpty; + for(;;) + { + if ( nextNonEmpty[i] == idx ) + { + nextNonEmpty[i] = nextNonEmpty[idx]; + return; + } + i = nextNonEmpty[i]; + } + } + /** * add a key value pair to the heap * @@ -89,7 +153,12 @@ public final class SortedHeap { al0[lp0-1] = key; vla0[lp0-1] = value; - lp[0]--; + lv[0] = al0[--lp[0]]; + if ( firstNonEmpty != 0 ) + { + nextNonEmpty[0] = firstNonEmpty; + firstNonEmpty = 0; + } return; } al0[lp0-1] = al0[lp0]; @@ -104,7 +173,6 @@ public final class SortedHeap int cnt = 4; // value count up to idx int idx = 1; int n = 8; - int firstNonEmptyIdx = 0; int nonEmptyCount = 1; for ( ;; ) @@ -123,7 +191,7 @@ public final class SortedHeap n <<= 1; } - // create it if not existant + // create, if not yet if ( al[idx] == null ) { al[idx] = new int[n]; @@ -137,59 +205,49 @@ public final class SortedHeap // now merge the contents of arrays 0...idx into idx while( nonEmptyCount > 1 ) { - int i = firstNonEmptyIdx; - int minId = al[i][lp[i]]; - int minIdx = i; + int neIdx = firstNonEmpty; + int minIdx = neIdx; + int minId = lv[minIdx]; - for ( i++; i <= idx; i++ ) + for ( int i = 1; i < nonEmptyCount; i++ ) { - if ( 4 << i > lp[i] ) + neIdx = nextNonEmpty[neIdx]; + if ( lv[neIdx] < minId ) { - int currentId = al[i][lp[i]]; - if ( currentId < minId ) - { - minIdx = i; - minId = currentId; - } + minIdx = neIdx; + minId = lv[neIdx]; } } // current minimum found, copy to target array - int sp = lp[minIdx]; // source-pointer al_t[tp] = minId; - vla_t[tp++] = vla[minIdx][sp]; - if ( minIdx != idx ) - { - vla[minIdx][sp] = null; - } - if ( ++lp[minIdx] == 4 << minIdx ) + vla_t[tp++] = dropLowest( minIdx ); + + if ( lp[minIdx] == 4 << minIdx ) { nonEmptyCount--; - if ( minIdx == firstNonEmptyIdx ) - { - while( lp[firstNonEmptyIdx] == 4 << firstNonEmptyIdx ) - { - firstNonEmptyIdx++; - } - } } } // only one non-empty index left, so just copy the remaining entries - if ( firstNonEmptyIdx != idx ) // no self-copy needed + if ( firstNonEmpty != idx ) // no self-copy needed { - int[] al_s = al[firstNonEmptyIdx]; - Object[] vla_s = vla[firstNonEmptyIdx]; - int sp = lp[firstNonEmptyIdx]; // source-pointer - while( sp < 4 << firstNonEmptyIdx ) + int[] al_s = al[firstNonEmpty]; + Object[] vla_s = vla[firstNonEmpty]; + int sp = lp[firstNonEmpty]; // source-pointer + while( sp < 4 << firstNonEmpty ) { al_t[tp] = al_s[sp]; vla_t[tp++] = vla_s[sp]; vla_s[sp++] = null; } - lp[firstNonEmptyIdx] = sp; + lp[firstNonEmpty] = sp; } + unlinkIdx( firstNonEmpty ); lp[idx] = n-cnt; // new target low pointer + lv[idx] = al[idx][lp[idx]]; + nextNonEmpty[idx] = firstNonEmpty; + firstNonEmpty = idx; } public void clear() @@ -209,11 +267,17 @@ public final class SortedHeap vla = new Object[MAXLISTS][]; vla[0] = new Object[4]; + lv = new int[MAXLISTS]; + nextNonEmpty = new int[MAXLISTS]; + + firstNonEmpty = -1; + int n = 4; for ( int idx = 0; idx < MAXLISTS; idx++ ) { lp[idx] = n; n <<= 1; + nextNonEmpty[idx] = -1; // no next } } } @@ -248,7 +312,7 @@ public final class SortedHeap { SortedHeap sh = new SortedHeap(); Random rnd = new Random(); - for( int i = 0; i< 6; i++ ) + for( int i = 0; i< 100; i++ ) { int val = rnd.nextInt( 1000000 ); sh.add( val, "" + val );