54 lines
1.6 KiB
Java
54 lines
1.6 KiB
Java
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 ab 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;
|
|
}
|
|
}
|