package org.exist.util; /** * A pool for byte arrays. * * This pool is primarily used while parsing documents: serializing the * DOM nodes generates a lot of small byte chunks. Only byte arrays * with length < MAX are kept in the pool. Large arrays are rarely * reused. */ public class ByteArrayPool { public static final int POOL_SIZE = 32; public static final int MAX = 128; public static final ThreadLocal<byte[][]> pools_ = new PoolThreadLocal(); private static int slot_ = 0; public ByteArrayPool() { //Nothing to do } public static byte[] getByteArray(int size) { final byte[][] pool = pools_.get(); if(size < MAX) { for(int i = pool.length; i-- > 0; ) { if(pool[i] != null && pool[i].length == size) { //System.out.println("found byte[" + size + "]"); final byte[] b = pool[i]; pool[i] = null; return b; } } } return new byte[size]; } public static void releaseByteArray(final byte[] b) { if(b == null || b.length > MAX) {return;} //System.out.println("releasing byte[" + b.length + "]"); final byte[][] pool = pools_.get(); for(int i = pool.length; i-- > 0;) { if(pool[i] == null) { pool[i] = b; return; } } int s = slot_++; if (s < 0) {s = -s;} pool[s % pool.length] = b; } private static final class PoolThreadLocal extends ThreadLocal<byte[][]> { @Override protected byte[][] initialValue() { return new byte[POOL_SIZE][]; } } }