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 pools_ = new PoolThreadLocal(); private static int slot_ = 0; public ByteArrayPool() { } public static byte[] getByteArray(int size) { byte[][] pool = (byte[][])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 + "]"); 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 + "]"); byte[][] pool = (byte[][]) 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 { protected Object initialValue() { return new byte[POOL_SIZE][]; } } }