package com.limegroup.gnutella.util; import java.util.Stack; /** * A cache of byte[]. Intended to allow a limited number of byte[]s to be created, * with methods for retrieving & returning them. When the maximum number is created, * further attempts to retrieve will block until others have been returned. */ public class ByteArrayCache { /** Default # of byte[]'s to hold. */ private static final int DEFAULT_SIZE = 512; /** Default length of returned bytes. */ private static final int DEFAULT_LENGTH = 1024; /** Holds cached byte[]'s for future re-use. */ private final Stack CACHE = new Stack(); /** The number of byte[]'s this cache has created that haven't been erased. */ private int _numCreated; /** The number of byte[]'s to create before blocking when the next one is gotten. */ private int _maxSize; /** The length of buffers to create. */ private int _length; /** Constructs a new ByteArraCache using the default size of 512 & length of 1024 */ public ByteArrayCache() { this(DEFAULT_SIZE, DEFAULT_LENGTH); } /** Constructs a new ByteArrayCache using the given maxSize & length. */ public ByteArrayCache(int maxSize, int length) { _maxSize = maxSize; _length = length; CACHE.ensureCapacity(maxSize); } /** * Attempts to retrieve a new byte[]. * If the cache is empty and getCreated() is >= getMaxSize(), this will block until * a byte[] is returned to the cache. */ public synchronized byte[] get() throws InterruptedException { while(true) { if (!CACHE.isEmpty()) { return (byte[]) CACHE.pop(); } else if (_numCreated < _maxSize) { _numCreated++; return new byte[_length]; } else { wait(); } } } /** * Returns a byte[] to this cache. * The byte[] MUST HAVE BEEN A byte[] RETURNED FROM get(). */ public synchronized void release(byte[] data) { CACHE.push(data); notifyAll(); } /** Clears all items in the cache. */ public synchronized void clear() { _numCreated -= CACHE.size(); CACHE.clear(); notifyAll(); } /** Returns the number of byte[]'s this cache has created. */ public synchronized int getCreated() { return _numCreated; } /** Returns the length of the byte[]'s this creates. */ public int getLength() { return _length; } /** Returns the maximum number of byte[]'s this will create. */ public int getMaxSize() { return _maxSize; } }