summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormukesh agrawal <quiche@google.com>2016-04-06 14:00:13 -0700
committermukesh agrawal <quiche@google.com>2016-04-07 17:07:44 -0700
commitca0bac5826ab430d1b765b201a609f7bc38401ee (patch)
tree5f82c5c525aa11eb1370a4bac7d43d3d7945f143
parentf37079e3d8f4aca3242a971cbaef732fe1b75bde (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.java35
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ByteArrayRingBufferTest.java43
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);
+ }
+
}