diff options
author | mukesh agrawal <quiche@google.com> | 2016-04-06 14:00:13 -0700 |
---|---|---|
committer | mukesh agrawal <quiche@google.com> | 2016-04-07 17:07:44 -0700 |
commit | ca0bac5826ab430d1b765b201a609f7bc38401ee (patch) | |
tree | 5f82c5c525aa11eb1370a4bac7d43d3d7945f143 | |
parent | f37079e3d8f4aca3242a971cbaef732fe1b75bde (diff) |
ByteArrayRingBuffer: add ability to resize buffer
When verbose mode is enabled, we'd like to use
larger ring buffers. To support this, add the
ability to resize a ByteArrayRingBuffer.
BUG=27578082
TEST=unit tests
Change-Id: I976a2ec05ade3f5c2c0fe5dc50cbb391534ab241
-rw-r--r-- | service/java/com/android/server/wifi/util/ByteArrayRingBuffer.java | 35 | ||||
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/ByteArrayRingBufferTest.java | 43 |
2 files changed, 69 insertions, 9 deletions
diff --git a/service/java/com/android/server/wifi/util/ByteArrayRingBuffer.java b/service/java/com/android/server/wifi/util/ByteArrayRingBuffer.java index 8fa9a47df..4341feeb3 100644 --- a/service/java/com/android/server/wifi/util/ByteArrayRingBuffer.java +++ b/service/java/com/android/server/wifi/util/ByteArrayRingBuffer.java @@ -23,15 +23,18 @@ import java.util.ArrayList; */ public class ByteArrayRingBuffer { private ArrayList<byte[]> mArrayList; - private final int mMaxBytes; + private int mMaxBytes; private int mBytesUsed; /** * Creates a ring buffer that holds at most |maxBytes| of data. The overhead for each element * is not included in this limit. - * @param maxBytes upper bound on the amount of data held + * @param maxBytes upper bound on the amount of data to hold */ public ByteArrayRingBuffer(int maxBytes) { + if (maxBytes < 1) { + throw new IllegalArgumentException(); + } mArrayList = new ArrayList<byte[]>(); mMaxBytes = maxBytes; mBytesUsed = 0; @@ -47,13 +50,7 @@ public class ByteArrayRingBuffer { * @return true if the data was added */ public boolean appendBuffer(byte[] newData) { - // Loop is O(n^2), but |n| is expected to be small. - while (mBytesUsed + newData.length > mMaxBytes - && !mArrayList.isEmpty()) { - mBytesUsed -= mArrayList.get(0).length; - mArrayList.remove(0); - } - + pruneToSize(mMaxBytes - newData.length); if (mBytesUsed + newData.length > mMaxBytes) { return false; } @@ -79,4 +76,24 @@ public class ByteArrayRingBuffer { public int getNumBuffers() { return mArrayList.size(); } + + /** + * Resize the buffer, removing existing data if necessary. + * @param maxBytes upper bound on the amount of data to hold + */ + public void resize(int maxBytes) { + pruneToSize(maxBytes); + mMaxBytes = maxBytes; + } + + private void pruneToSize(int sizeBytes) { + int newBytesUsed = mBytesUsed; + int i = 0; + while (i < mArrayList.size() && newBytesUsed > sizeBytes) { + newBytesUsed -= mArrayList.get(i).length; + i++; + } + mArrayList.subList(0, i).clear(); + mBytesUsed = newBytesUsed; + } } diff --git a/tests/wifitests/src/com/android/server/wifi/ByteArrayRingBufferTest.java b/tests/wifitests/src/com/android/server/wifi/ByteArrayRingBufferTest.java index dcf4cfbd4..f359cfd93 100644 --- a/tests/wifitests/src/com/android/server/wifi/ByteArrayRingBufferTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ByteArrayRingBufferTest.java @@ -150,4 +150,47 @@ public class ByteArrayRingBufferTest { assertFalse(rb.appendBuffer(data2)); assertEquals(0, rb.getNumBuffers()); } + + /** Verifies resizes()'s behavior when shrinking the buffer: + * 1) Existing data is pruned. + * 2) We really do decrease the size limit. + */ + @Test + public void resizePrunesDataAndUpdatesSizeLimitOnShrink() { + final ByteArrayRingBuffer rb = new ByteArrayRingBuffer(MAX_BYTES); + assertTrue(rb.appendBuffer(new byte[MAX_BYTES])); + + final byte newSize = 1; + rb.resize(newSize); + assertEquals(0, rb.getNumBuffers()); + assertFalse(rb.appendBuffer(new byte[newSize + 1])); + } + + /** Verifies resize()'s behavior when growing the buffer: + * 1) Existing data is retained. + * 2) We really do increase the size limit. + */ + @Test + public void resizeRetainsExistingDataAndUpdatesSizeLimitOnGrow() { + final ByteArrayRingBuffer rb = new ByteArrayRingBuffer(MAX_BYTES); + assertTrue(rb.appendBuffer(new byte[MAX_BYTES])); + rb.resize(MAX_BYTES * 2); + assertTrue(rb.appendBuffer(new byte[MAX_BYTES])); + assertEquals(2, rb.getNumBuffers()); + } + + /** Verifies that we don't crash when shrinking an empty buffer. */ + @Test + public void shrinkingEmptyBufferSucceeds() { + final ByteArrayRingBuffer rb = new ByteArrayRingBuffer(MAX_BYTES * 2); + rb.resize(MAX_BYTES); + } + + /** Verifies that we don't crash when growing an empty buffer. */ + @Test + public void growingEmptyBufferSucceeds() { + final ByteArrayRingBuffer rb = new ByteArrayRingBuffer(MAX_BYTES); + rb.resize(MAX_BYTES * 2); + } + } |