package btools.util; public final class ByteArrayUnifier implements IByteArrayUnifier { private byte[][] byteArrayCache; private int[] crcCrosscheck; private int size; public ByteArrayUnifier( int size, boolean validateImmutability ) { this.size = size; byteArrayCache = new byte[size][]; if ( validateImmutability ) crcCrosscheck = new int[size]; } /** * Unify a byte array in order to reuse instances when possible. * The byte arrays are assumed to be treated as immutable, * allowing the reuse * @param the byte array to unify * @return the cached instance or the input instanced if not cached */ public byte[] unify( byte[] ab ) { return unify( ab, 0, ab.length ); } public byte[] unify( byte[] ab, int offset, int len ) { int crc = Crc32.crc( ab, offset, len ); int idx = ( crc & 0xfffffff ) % size; byte[] abc = byteArrayCache[idx]; if ( abc != null && abc.length == len ) { int i = 0; while (i < len) { if ( ab[offset + i] != abc[i] ) break; i++; } if ( i == len ) return abc; } if ( crcCrosscheck != null ) { if ( byteArrayCache[idx] != null ) { byte[] abold = byteArrayCache[idx]; int crcold = Crc32.crc( abold, 0, abold.length ); if ( crcold != crcCrosscheck[idx] ) throw new IllegalArgumentException( "ByteArrayUnifier: immutablity validation failed!" ); } crcCrosscheck[idx] = crc; } byte[] nab = new byte[len]; System.arraycopy( ab, offset, nab, 0, len ); byteArrayCache[idx] = nab; return nab; } }