@Test public void reusesBuffer() { ByteArrayPool pool = new ByteArrayPool(32); byte[] buf1 = pool.getBuf(16); byte[] buf2 = pool.getBuf(16); pool.returnBuf(buf1); pool.returnBuf(buf2); byte[] buf3 = pool.getBuf(16); byte[] buf4 = pool.getBuf(16); assertTrue(buf3 == buf1 || buf3 == buf2); assertTrue(buf4 == buf1 || buf4 == buf2); assertTrue(buf3 != buf4); }
/** * Returns a buffer to the pool, throwing away old buffers if the pool would exceed its allotted * size. * * @param buf the buffer to return to the pool. */ public synchronized void returnBuf(byte[] buf) { if (buf == null || buf.length > mSizeLimit) { return; } mBuffersByLastUse.add(buf); int pos = Collections.binarySearch(mBuffersBySize, buf, BUF_COMPARATOR); if (pos < 0) { pos = -pos - 1; } mBuffersBySize.add(pos, buf); mCurrentSize += buf.length; trim(); }
/** * Ensures there is enough space in the buffer for the given number of additional bytes. */ private void expand(int i) { /* Can the buffer handle @i more bytes, if not expand it */ if (count + i <= buf.length) { return; } byte[] newbuf = mPool.getBuf((count + i) * 2); System.arraycopy(buf, 0, newbuf, 0, count); mPool.returnBuf(buf); buf = newbuf; }
/** * @param httpStack HTTP stack to be used */ public BasicNetwork(HttpStack httpStack) { // If a pool isn't passed in, then build a small default pool that will give us a lot of // benefit and not use too much memory. this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE)); }
@Override public void finalize() { mPool.returnBuf(buf); }
/** * Constructs a new {@code ByteArrayOutputStream} with a default size of {@code size} bytes. If * more than {@code size} bytes are written to this instance, the underlying byte array will * expand. * * @param size initial size for the underlying byte array. The value will be pinned to a default * minimum size. */ public PoolingByteArrayOutputStream(ByteArrayPool pool, int size) { mPool = pool; buf = mPool.getBuf(Math.max(size, DEFAULT_SIZE)); }
/** * Ensures there is enough space in the buffer for the given number of additional bytes. */ private void expand(int i) { /* Can the buffer handle @i more bytes, if not expand it */ if (count + i <= buf.length) { return; } byte[] newbuf = mPool.getBuf((count + i) * 2); System.arraycopy(buf, 0, newbuf, 0, count); mPool.returnBuf(buf); buf = newbuf; }
/** * @param httpStack HTTP stack to be used */ public BasicNetwork(HttpStack httpStack) { // If a pool isn't passed in, then build a small default pool that will give us a lot of // benefit and not use too much memory. this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE)); }
@Override public void finalize() { mPool.returnBuf(buf); }
/** * Constructs a new {@code ByteArrayOutputStream} with a default size of {@code size} bytes. If * more than {@code size} bytes are written to this instance, the underlying byte array will * expand. * * @param size initial size for the underlying byte array. The value will be pinned to a default * minimum size. */ public PoolingByteArrayOutputStream(ByteArrayPool pool, int size) { mPool = pool; buf = mPool.getBuf(Math.max(size, DEFAULT_SIZE)); }
@Test public void returnsBufferWithRightSize() { ByteArrayPool pool = new ByteArrayPool(32); byte[] buf1 = pool.getBuf(16); pool.returnBuf(buf1); byte[] buf2 = pool.getBuf(17); assertNotSame(buf2, buf1); byte[] buf3 = pool.getBuf(15); assertSame(buf3, buf1); } }
/** * Ensures there is enough space in the buffer for the given number of additional bytes. */ private void expand(int i) { /* Can the buffer handle @i more bytes, if not expand it */ if (count + i <= buf.length) { return; } byte[] newbuf = mPool.getBuf((count + i) * 2); System.arraycopy(buf, 0, newbuf, 0, count); mPool.returnBuf(buf); buf = newbuf; }
/** * @param httpStack HTTP stack to be used */ public BasicNetwork(HttpStack httpStack) { // If a pool isn't passed in, then build a small default pool that will give us a lot of // benefit and not use too much memory. this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE)); }
@Override public void finalize() { mPool.returnBuf(buf); }
/** * Constructs a new {@code ByteArrayOutputStream} with a default size of {@code size} bytes. If * more than {@code size} bytes are written to this instance, the underlying byte array will * expand. * * @param size initial size for the underlying byte array. The value will be pinned to a default * minimum size. */ public PoolingByteArrayOutputStream(ByteArrayPool pool, int size) { mPool = pool; buf = mPool.getBuf(Math.max(size, DEFAULT_SIZE)); }
/** * Returns a buffer to the pool, throwing away old buffers if the pool would exceed its allotted * size. * * @param buf the buffer to return to the pool. */ public synchronized void returnBuf(byte[] buf) { if (buf == null || buf.length > mSizeLimit) { return; } mBuffersByLastUse.add(buf); int pos = Collections.binarySearch(mBuffersBySize, buf, BUF_COMPARATOR); if (pos < 0) { pos = -pos - 1; } mBuffersBySize.add(pos, buf); mCurrentSize += buf.length; trim(); }
@Test public void reusesBuffer() { ByteArrayPool pool = new ByteArrayPool(32); byte[] buf1 = pool.getBuf(16); byte[] buf2 = pool.getBuf(16); pool.returnBuf(buf1); pool.returnBuf(buf2); byte[] buf3 = pool.getBuf(16); byte[] buf4 = pool.getBuf(16); assertTrue(buf3 == buf1 || buf3 == buf2); assertTrue(buf4 == buf1 || buf4 == buf2); assertTrue(buf3 != buf4); }
/** Reads the contents of HttpEntity into a byte[]. */ private byte[] entityToBytes(HttpEntity entity) throws IOException, ServerError { PoolingByteArrayOutputStream bytes = new PoolingByteArrayOutputStream(mPool, (int) entity.getContentLength()); byte[] buffer = null; try { InputStream in = entity.getContent(); if (in == null) { throw new ServerError(); } buffer = mPool.getBuf(1024); int count; while ((count = in.read(buffer)) != -1) { bytes.write(buffer, 0, count); } return bytes.toByteArray(); } finally { try { // Close the InputStream and release the resources by "consuming the content". entity.consumeContent(); } catch (IOException e) { // This can happen if there was an exception above that left the entity in // an invalid state. VolleyLog.v("Error occured when calling consumingContent"); } mPool.returnBuf(buffer); bytes.close(); } }
@Test public void pooledIndividualWrites() throws IOException { ByteArrayPool pool = new ByteArrayPool(32768); writeBytesIndividually(pool); writeBytesIndividually(pool); writeBytesIndividually(pool); }
@Override public void close() throws IOException { mPool.returnBuf(buf); buf = null; super.close(); }