package org.limewire.collection;
/**
* Creates a byte array with a size that is a power of 2 (byte array size = 2^power).
* If you try to get a byte array with a size that is not a power of two, the value
* is set to the next power of 2. For example, setting a value of 511 returns a byte
* array of size 512 because 511 is not a power of 2 (2^8 = 256 and 2^9 = 512).
* (If you attempt to create a byte array less than a size zero (base 2^-2),
* the size is set to 1.)
* <p>
* Additionally, <code>PowerOf2ByteArrayCache</code> stores the total size of
* cached byte[]s.
* <pre>
PowerOf2ByteArrayCache p2 = new PowerOf2ByteArrayCache();
byte[] ba4 = p2.get(4);
System.out.println("ba4 size: " + ba4.length + " cache size is " + p2.getCacheSize());
byte[] ba5 = p2.get(5);
System.out.println("ba5 size: " + ba5.length + " cache size is " + p2.getCacheSize());
byte[] ba8 = p2.get(8);
System.out.println("ba8 size: " + ba8.length + " cache size is " + p2.getCacheSize());
byte[] ba9 = p2.get(9);
System.out.println("ba9 size: " + ba9.length + " cache size is " + p2.getCacheSize());
Output:
ba4 size: 4 cache size is 4
ba5 size: 8 cache size is 12
ba8 size: 8 cache size is 12
ba9 size: 16 cache size is 28
</pre>
*/
public class PowerOf2ByteArrayCache {
private final IntHashMap<byte[]> CACHE = new IntHashMap<byte[]>(20);
private volatile int totalStored = 0;
/**
* @return a byte array of the specified size, using cached one
* if possible.
*/
public byte [] get(int size) {
int exp;
for (exp = 1 ; exp < size ; exp*=2);
// exp is now >= size. it will be equal
// to size if size was a power of two.
// otherwise, it will be the first power of 2
// greater than size.
// since we want to cache only powers of two,
// we will use exp from hereon.
byte[] ret = CACHE.get(exp);
if (ret == null) {
ret = new byte[exp];
totalStored += exp;
CACHE.put(exp, ret);
}
return ret;
}
public int getCacheSize() {
return totalStored;
}
/** Erases all data in the cache. */
public void clear() {
CACHE.clear();
totalStored = 0;
}
}