Skip to content

Commit fb6057d

Browse files
committed
fix: FramePool keeps undersized frames instead of discarding them
obtain() looks at each pooled frame of the size class at most once and puts undersized ones back, so a smaller buffer in front of a suitable one no longer causes an allocation and a lost buffer.
1 parent 8c26ffb commit fb6057d

2 files changed

Lines changed: 22 additions & 5 deletions

File tree

‎android/app/src/main/java/com/openipc/decoder/FramePool.java‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,16 @@ class FramePool {
3030
}
3131

3232
Frame obtain(int size) {
33-
boolean isSmall = size <= SMALL_MAX;
34-
Frame frame = (isSmall ? small : large).poll();
35-
if (frame != null && frame.data().length >= size) {
36-
frame.setLength(0);
37-
return frame;
33+
BlockingQueue<Frame> queue = size <= SMALL_MAX ? small : large;
34+
// Look at each pooled frame at most once; undersized ones go back for later requests
35+
for (int i = queue.size(); i > 0; i--) {
36+
Frame frame = queue.poll();
37+
if (frame == null) break;
38+
if (frame.data().length >= size) {
39+
frame.setLength(0);
40+
return frame;
41+
}
42+
queue.offer(frame);
3843
}
3944
// Round the capacity up so that the frame can be reused for similar sizes
4045
return new Frame(new byte[capacityFor(size)], 0);

‎android/app/src/test/java/com/openipc/decoder/FramePoolTest.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,16 @@ public void largeClassIsBounded() {
5656
assertSame(f[1], pool.obtain(300_000));
5757
assertNotSame(f[2], pool.obtain(300_000)); // the third was dropped, not retained
5858
}
59+
60+
@Test
61+
public void undersizedFramesAreKeptNotDiscarded() {
62+
FramePool pool = new FramePool(8);
63+
Frame small = pool.obtain(1000); // 2 KiB
64+
Frame bigger = pool.obtain(10_000); // 16 KiB
65+
pool.recycle(small);
66+
pool.recycle(bigger);
67+
// A 10 KB request skips the 2 KiB frame without losing it
68+
assertSame(bigger, pool.obtain(10_000));
69+
assertSame(small, pool.obtain(1000));
70+
}
5971
}

0 commit comments

Comments
 (0)