Skip to content

Commit aa616a9

Browse files
committed
test: extract FixSizeBufferPoolTest
1 parent 14eedcb commit aa616a9

File tree

2 files changed

+306
-227
lines changed

2 files changed

+306
-227
lines changed
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
/*
2+
* Copyright The Dongting Project
3+
*
4+
* The Dongting Project licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
package com.github.dtprj.dongting.buf;
17+
18+
import com.github.dtprj.dongting.common.Timestamp;
19+
import org.junit.jupiter.api.Test;
20+
21+
import java.nio.ByteBuffer;
22+
23+
import static org.junit.jupiter.api.Assertions.*;
24+
25+
/**
26+
* @author huangli
27+
*/
28+
public class FixSizeBufferPoolTest {
29+
30+
private static final Timestamp TS = new Timestamp();
31+
32+
private SimpleByteBufferPoolConfig createTestConfig() {
33+
// just use currentUsedShareSize field, so set other params to invalid value
34+
return new SimpleByteBufferPoolConfig(TS, false, 0, false,
35+
null, null, null);
36+
}
37+
38+
private FixSizeBufferPool createFixPool(int bufferSize, int minCount, int maxCount, long shareSize) {
39+
SimpleByteBufferPoolConfig config = createTestConfig();
40+
return new FixSizeBufferPool(config, false, shareSize, minCount, maxCount, bufferSize, 4096);
41+
}
42+
43+
private FixSizeBufferPool createFixPool(int bufferSize, int minCount, int maxCount) {
44+
return createFixPool(bufferSize, minCount, maxCount, 0);
45+
}
46+
47+
private ByteBuffer borrowOrAllocate(FixSizeBufferPool pool, int size) {
48+
ByteBuffer buf = pool.borrow();
49+
return buf != null ? buf : ByteBuffer.allocate(size);
50+
}
51+
52+
@Test
53+
public void testShareSize() {
54+
FixSizeBufferPool pool = createFixPool(200, 1, 2, 500);
55+
ByteBuffer buf1 = ByteBuffer.allocate(200);
56+
ByteBuffer buf2 = ByteBuffer.allocate(200);
57+
ByteBuffer buf3 = ByteBuffer.allocate(200);
58+
ByteBuffer buf4 = ByteBuffer.allocate(200);
59+
ByteBuffer buf5 = ByteBuffer.allocate(200);
60+
61+
pool.release(buf1, TS.nanoTime);
62+
pool.release(buf2, TS.nanoTime);
63+
pool.release(buf3, TS.nanoTime);
64+
pool.release(buf4, TS.nanoTime);
65+
pool.release(buf5, TS.nanoTime);
66+
67+
assertSame(buf4, pool.borrow());
68+
TS.nanoTime += 1001;
69+
pool.clean(TS.nanoTime);
70+
assertSame(buf3, pool.borrow());
71+
}
72+
73+
@Test
74+
public void testClean1() {
75+
// Test: no cleanup when time elapsed < timeout (500ms < 1000ms)
76+
long timeoutMillis = 1000;
77+
long timeoutNanos = timeoutMillis * 1000 * 1000;
78+
79+
FixSizeBufferPool pool = createFixPool(128, 1, 2);
80+
ByteBuffer buf1 = ByteBuffer.allocate(128);
81+
ByteBuffer buf2 = ByteBuffer.allocate(128);
82+
pool.release(buf1, TS.nanoTime);
83+
pool.release(buf2, TS.nanoTime);
84+
85+
TS.nanoTime += 500 * 1000 * 1000;
86+
long expireNanos = TS.nanoTime - timeoutNanos;
87+
pool.clean(expireNanos);
88+
89+
ByteBuffer buf3 = pool.borrow();
90+
ByteBuffer buf4 = pool.borrow();
91+
assertSame(buf2, buf3);
92+
assertSame(buf1, buf4);
93+
pool.release(buf1, TS.nanoTime);
94+
pool.release(buf2, TS.nanoTime);
95+
}
96+
97+
@Test
98+
public void testClean2() {
99+
// Test: cleanup to minCount when time elapsed > timeout (minCount=1, maxCount=3)
100+
long timeoutMillis = 1000;
101+
long timeoutNanos = timeoutMillis * 1000 * 1000;
102+
103+
FixSizeBufferPool pool = createFixPool(128, 1, 3);
104+
ByteBuffer buf1 = ByteBuffer.allocate(128);
105+
ByteBuffer buf2 = ByteBuffer.allocate(128);
106+
ByteBuffer buf3 = ByteBuffer.allocate(128);
107+
pool.release(buf1, TS.nanoTime);
108+
pool.release(buf2, TS.nanoTime);
109+
pool.release(buf3, TS.nanoTime);
110+
111+
for (int i = 0; i < 5; i++) {
112+
TS.nanoTime += 1001 * 1000 * 1000;
113+
long expireNanos = TS.nanoTime - timeoutNanos;
114+
pool.clean(expireNanos);
115+
116+
ByteBuffer buf4 = borrowOrAllocate(pool, 128);
117+
ByteBuffer buf5 = borrowOrAllocate(pool, 128);
118+
ByteBuffer buf6 = borrowOrAllocate(pool, 128);
119+
assertSame(buf3, buf4);
120+
assertTrue(buf5 != buf1 && buf5 != buf2 && buf5 != buf3);
121+
assertTrue(buf6 != buf1 && buf6 != buf2 && buf6 != buf3);
122+
123+
buf1 = buf4;
124+
buf2 = buf5;
125+
buf3 = buf6;
126+
pool.release(buf1, TS.nanoTime);
127+
pool.release(buf2, TS.nanoTime);
128+
pool.release(buf3, TS.nanoTime);
129+
}
130+
}
131+
132+
@Test
133+
public void testClean3() {
134+
// Test: cleanup to minCount when time elapsed > timeout (minCount=1, maxCount=2)
135+
long timeoutMillis = 1000;
136+
long timeoutNanos = timeoutMillis * 1000 * 1000;
137+
138+
FixSizeBufferPool pool = createFixPool(128, 1, 2);
139+
ByteBuffer buf1 = ByteBuffer.allocate(128);
140+
ByteBuffer buf2 = ByteBuffer.allocate(128);
141+
pool.release(buf1, TS.nanoTime);
142+
pool.release(buf2, TS.nanoTime);
143+
144+
for (int i = 0; i < 5; i++) {
145+
TS.nanoTime += 1001 * 1000 * 1000;
146+
long expireNanos = TS.nanoTime - timeoutNanos;
147+
pool.clean(expireNanos);
148+
149+
ByteBuffer buf3 = borrowOrAllocate(pool, 128);
150+
ByteBuffer buf4 = borrowOrAllocate(pool, 128);
151+
assertSame(buf2, buf3);
152+
assertTrue(buf4 != buf1 && buf4 != buf2);
153+
154+
buf1 = buf3;
155+
buf2 = buf4;
156+
pool.release(buf1, TS.nanoTime);
157+
pool.release(buf2, TS.nanoTime);
158+
}
159+
}
160+
161+
@Test
162+
public void testClean4() {
163+
// Test: cleanup all buffers when minCount=0 and time elapsed > timeout
164+
long timeoutMillis = 1000;
165+
long timeoutNanos = timeoutMillis * 1000 * 1000;
166+
167+
FixSizeBufferPool pool = createFixPool(128, 0, 2);
168+
ByteBuffer buf1 = ByteBuffer.allocate(128);
169+
ByteBuffer buf2 = ByteBuffer.allocate(128);
170+
pool.release(buf1, TS.nanoTime);
171+
pool.release(buf2, TS.nanoTime);
172+
173+
for (int i = 0; i < 5; i++) {
174+
TS.nanoTime += 1001 * 1000 * 1000;
175+
long expireNanos = TS.nanoTime - timeoutNanos;
176+
pool.clean(expireNanos);
177+
178+
ByteBuffer buf3 = borrowOrAllocate(pool, 128);
179+
ByteBuffer buf4 = borrowOrAllocate(pool, 128);
180+
assertTrue(buf3 != buf1 && buf3 != buf2);
181+
assertTrue(buf4 != buf1 && buf4 != buf2);
182+
183+
buf1 = buf3;
184+
buf2 = buf4;
185+
pool.release(buf1, TS.nanoTime);
186+
pool.release(buf2, TS.nanoTime);
187+
}
188+
}
189+
190+
@Test
191+
public void testWeakRefNotEnabledForDirect() {
192+
SimpleByteBufferPoolConfig config = createTestConfig();
193+
FixSizeBufferPool pool = new FixSizeBufferPool(config, true, 0, 1, 2, 128, 128);
194+
ByteBuffer buf1 = ByteBuffer.allocateDirect(128);
195+
ByteBuffer buf2 = ByteBuffer.allocateDirect(128);
196+
ByteBuffer buf3 = ByteBuffer.allocateDirect(128);
197+
pool.release(buf1, TS.nanoTime);
198+
pool.release(buf2, TS.nanoTime);
199+
pool.release(buf3, TS.nanoTime);
200+
assertSame(buf2, pool.borrow());
201+
assertSame(buf1, pool.borrow());
202+
assertNotSame(buf3, pool.borrow());
203+
}
204+
205+
@Test
206+
public void testWeakRefNotEnabledForSmallBuffer() {
207+
SimpleByteBufferPoolConfig config = createTestConfig();
208+
FixSizeBufferPool pool = new FixSizeBufferPool(config, false, 0, 1, 2, 128, 256);
209+
ByteBuffer buf1 = ByteBuffer.allocate(128);
210+
ByteBuffer buf2 = ByteBuffer.allocate(128);
211+
ByteBuffer buf3 = ByteBuffer.allocate(128);
212+
pool.release(buf1, TS.nanoTime);
213+
pool.release(buf2, TS.nanoTime);
214+
pool.release(buf3, TS.nanoTime);
215+
assertSame(buf2, pool.borrow());
216+
assertSame(buf1, pool.borrow());
217+
assertNotSame(buf3, pool.borrow());
218+
}
219+
220+
@Test
221+
public void testWeakRefReleaseToWeakStack() {
222+
for (int attempt = 0; attempt < 3; attempt++) {
223+
SimpleByteBufferPoolConfig config = createTestConfig();
224+
FixSizeBufferPool pool = new FixSizeBufferPool(config, false, 0, 1, 2, 128, 128);
225+
ByteBuffer buf1 = ByteBuffer.allocate(128);
226+
ByteBuffer buf2 = ByteBuffer.allocate(128);
227+
ByteBuffer buf3 = ByteBuffer.allocate(128);
228+
pool.release(buf1, TS.nanoTime);
229+
pool.release(buf2, TS.nanoTime);
230+
pool.release(buf3, TS.nanoTime);
231+
ByteBuffer b1 = pool.borrow();
232+
ByteBuffer b2 = pool.borrow();
233+
ByteBuffer b3 = pool.borrow();
234+
if (b1 == buf3 && b2 == buf2 && b3 == buf1) {
235+
return;
236+
}
237+
}
238+
fail("weak ref test failed after 3 attempts");
239+
}
240+
241+
@Test
242+
public void testWeakRefCleanToWeakStack() {
243+
for (int attempt = 0; attempt < 3; attempt++) {
244+
SimpleByteBufferPoolConfig config = createTestConfig();
245+
FixSizeBufferPool pool = new FixSizeBufferPool(config, false, 0, 1, 3, 128, 128);
246+
ByteBuffer buf1 = ByteBuffer.allocate(128);
247+
ByteBuffer buf2 = ByteBuffer.allocate(128);
248+
ByteBuffer buf3 = ByteBuffer.allocate(128);
249+
pool.release(buf1, TS.nanoTime);
250+
pool.release(buf2, TS.nanoTime);
251+
pool.release(buf3, TS.nanoTime);
252+
253+
TS.nanoTime += 1001;
254+
pool.clean(TS.nanoTime);
255+
256+
ByteBuffer buf4 = pool.borrow();
257+
ByteBuffer buf5 = pool.borrow();
258+
ByteBuffer buf6 = pool.borrow();
259+
260+
if (buf4 == buf1 && buf5 == buf2 && buf6 == buf3) {
261+
return;
262+
}
263+
}
264+
fail("weak ref test failed after 3 attempts");
265+
}
266+
267+
@Test
268+
public void testWeakRefGCAndClean() {
269+
SimpleByteBufferPoolConfig config = createTestConfig();
270+
FixSizeBufferPool testPool = new FixSizeBufferPool(config, false, 1, 0, 1, 128, 128);
271+
272+
ByteBuffer buf1 = ByteBuffer.allocate(128);
273+
ByteBuffer buf2 = ByteBuffer.allocate(128);
274+
ByteBuffer buf3 = ByteBuffer.allocate(128);
275+
testPool.release(buf1, TS.nanoTime);
276+
testPool.release(buf2, TS.nanoTime);
277+
testPool.release(buf3, TS.nanoTime);
278+
279+
//noinspection UnusedAssignment
280+
buf2 = null;
281+
282+
System.gc();
283+
System.runFinalization();
284+
285+
TS.nanoTime += 1001;
286+
testPool.clean(TS.nanoTime);
287+
288+
ByteBuffer borrowed1 = testPool.borrow();
289+
ByteBuffer borrowed2 = testPool.borrow();
290+
291+
assertNotNull(borrowed1);
292+
assertNotNull(borrowed2);
293+
assertEquals(128, borrowed1.capacity());
294+
assertEquals(128, borrowed2.capacity());
295+
}
296+
}

0 commit comments

Comments
 (0)