initial commit of BRouter Version 0.98

This commit is contained in:
Arndt Brenschede 2014-01-18 15:29:05 +01:00
parent e4ae2b37d3
commit 91e62f1164
120 changed files with 15382 additions and 0 deletions

View file

@ -0,0 +1,206 @@
package btools.util;
/**
* TinyDenseLongMap implements the DenseLongMap interface
* but actually is made for a medium count of non-dense keys
*
* It's used as a replacement for DenseLongMap where we
* have limited memory and far less keys than maykey
*
* @author ab
*/
public class TinyDenseLongMap extends DenseLongMap
{
private long[][] al;
private int[] pa;
private int size = 0;
private int _maxKeepExponent = 14; // the maximum exponent to keep the invalid arrays
protected static final int MAXLISTS = 31; // enough for size Integer.MAX_VALUE
public TinyDenseLongMap()
{
super(1);
// pointer array
pa = new int[MAXLISTS];
// allocate key lists
al = new long[MAXLISTS][];
al[0] = new long[1]; // make the first array (the transient buffer)
// same for the values
vla = new byte[MAXLISTS][];
vla[0] = new byte[1];
}
private byte[][] vla; // value list array
private void fillReturnValue(byte[] rv, int idx, int p )
{
rv[0] = vla[idx][p];
if ( rv.length == 2 )
{
vla[idx][p] = rv[1];
}
}
@Override
public void put( long id, int value )
{
byte[] rv = new byte[2];
rv[1] = (byte)value;
if ( contains( id, rv ) )
{
return;
}
vla[0][0] = (byte)value;
_add( id );
}
/**
* Get the byte for the given id
* @param id the key to query
* @return the object
* @exception IllegalArgumentException if id is unknown
*/
@Override
public int getInt( long id )
{
byte[] rv = new byte[1];
if ( contains( id, rv ) )
{
return rv[0];
}
return -1;
}
private boolean _add( long id )
{
if ( size == Integer.MAX_VALUE )
{
throw new IllegalArgumentException( "cannot grow beyond size Integer.MAX_VALUE" );
}
// put the new entry in the first array
al[0][0] = id;
// determine the first empty array
int bp = size++; // treat size as bitpattern
int idx = 1;
int n = 1;
pa[0] = 1;
pa[1] = 1;
while ( (bp&1) == 1 )
{
bp >>= 1;
pa[idx++] = n;
n <<= 1;
}
// create it if not existant
if ( al[idx] == null )
{
al[idx] = new long[n];
vla[idx] = new byte[n];
}
// now merge the contents of arrays 0...idx-1 into idx
while ( n > 0 )
{
long maxId = 0;
int maxIdx = -1;
for ( int i=0; i<idx; i++ )
{
int p = pa[i];
if ( p > 0 )
{
long currentId = al[i][p-1];
if ( maxIdx < 0 || currentId > maxId )
{
maxIdx = i;
maxId = currentId;
}
}
}
// current maximum found, copy to target array
if ( n < al[idx].length && maxId == al[idx][n] )
{
throw new IllegalArgumentException( "duplicate key found in late check: " + maxId );
}
--n;
al[idx][n] = maxId;
vla[idx][n] = vla[maxIdx][pa[maxIdx]-1];
--pa[maxIdx];
}
// de-allocate empty arrays of a certain size (fix at 64kByte)
while ( idx-- > _maxKeepExponent )
{
al[idx] = null;
vla[idx] = null;
}
return false;
}
private boolean contains( long id, byte[] rv )
{
// determine the first empty array
int bp = size; // treat size as bitpattern
int idx = 1;
while ( bp != 0 )
{
if ( (bp&1) == 1 )
{
// array at idx is valid, check
if ( contains( idx, id, rv ) )
{
return true;
}
}
idx++;
bp >>= 1;
}
return false;
}
// does sorted array "a" contain "id" ?
private boolean contains( int idx, long id, byte[] rv )
{
long[] a = al[idx];
int offset = a.length;
int n = 0;
while ( (offset >>= 1) > 0 )
{
int nn = n + offset;
if ( a[nn] <= id )
{
n = nn;
}
}
if ( a[n] == id )
{
if ( rv != null )
{
fillReturnValue( rv, idx, n );
}
return true;
}
return false;
}
}