Skip to content

Commit 33c4260

Browse files
committed
Fixes #1262: Add diagnostic method pooledCount() in RecyclerPool (#1263)
(backport to 2.17.1 to help testing)
1 parent c73bde2 commit 33c4260

File tree

3 files changed

+96
-25
lines changed

3 files changed

+96
-25
lines changed

src/main/java/com/fasterxml/jackson/core/util/RecyclerPool.java

+55-6
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,25 @@ default boolean clear() {
111111
return false;
112112
}
113113

114+
/**
115+
* Diagnostic method for obtaining an estimate of number of pooled items
116+
* this pool contains, available for recycling.
117+
* Note that in addition to this information possibly not being available
118+
* (denoted by return value of {@code -1}) even when available this may be
119+
* just an approximation.
120+
*<p>
121+
* Default method implementation simply returns {@code -1} and is meant to be
122+
* overridden by concrete sub-classes.
123+
*
124+
* @return Number of pooled entries available from this pool, if available;
125+
* {@code -1} if not.
126+
*
127+
* @since 2.18
128+
*/
129+
default int pooledCount() {
130+
return -1;
131+
}
132+
114133
/*
115134
/**********************************************************************
116135
/* Partial/base RecyclerPool implementations
@@ -150,6 +169,12 @@ public void releasePooled(P pooled) {
150169
// nothing to do, relies on ThreadLocal
151170
}
152171

172+
// No way to actually even estimate...
173+
@Override
174+
public int pooledCount() {
175+
return -1;
176+
}
177+
153178
// Due to use of ThreadLocal no tracking available; cannot clear
154179
@Override
155180
public boolean clear() {
@@ -181,6 +206,11 @@ public void releasePooled(P pooled) {
181206
// nothing to do, there is no underlying pool
182207
}
183208

209+
@Override
210+
public int pooledCount() {
211+
return 0;
212+
}
213+
184214
/**
185215
* Although no pooling occurs, we consider clearing to succeed,
186216
* so returns always {@code true}.
@@ -262,6 +292,11 @@ public void releasePooled(P pooled) {
262292
pool.offerLast(pooled);
263293
}
264294

295+
@Override
296+
public int pooledCount() {
297+
return pool.size();
298+
}
299+
265300
@Override
266301
public boolean clear() {
267302
pool.clear();
@@ -322,13 +357,13 @@ public void releasePooled(P pooled) {
322357
}
323358
}
324359

325-
protected static class Node<P> {
326-
final P value;
327-
Node<P> next;
328-
329-
Node(P value) {
330-
this.value = value;
360+
@Override
361+
public int pooledCount() {
362+
int count = 0;
363+
for (Node<P> curr = head.get(); curr != null; curr = curr.next) {
364+
++count;
331365
}
366+
return count;
332367
}
333368

334369
// Yes, we can clear it
@@ -337,6 +372,15 @@ public boolean clear() {
337372
head.set(null);
338373
return true;
339374
}
375+
376+
protected static class Node<P> {
377+
final P value;
378+
Node<P> next;
379+
380+
Node(P value) {
381+
this.value = value;
382+
}
383+
}
340384
}
341385

342386
/**
@@ -385,6 +429,11 @@ public void releasePooled(P pooled) {
385429
pool.offer(pooled);
386430
}
387431

432+
@Override
433+
public int pooledCount() {
434+
return pool.size();
435+
}
436+
388437
@Override
389438
public boolean clear() {
390439
pool.clear();

src/test/java/com/fasterxml/jackson/core/io/BufferRecyclerPoolTest.java

+5
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ public void releasePooled(BufferRecycler r) {
130130
bufferRecycler = r;
131131
}
132132

133+
@Override
134+
public int pooledCount() {
135+
return (bufferRecycler == null) ? 0 : 1;
136+
}
137+
133138
@Override
134139
public boolean clear() {
135140
bufferRecycler = null;

src/test/java/com/fasterxml/jackson/core/util/JsonBufferRecyclersTest.java

+36-19
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,41 @@ class JsonBufferRecyclersTest extends JUnit5TestBase
1616

1717
@Test
1818
void parserWithThreadLocalPool() throws Exception {
19-
_testParser(JsonRecyclerPools.threadLocalPool());
19+
_testParser(JsonRecyclerPools.threadLocalPool(), -1, -1);
2020
}
2121

2222
@Test
2323
void parserWithNopLocalPool() throws Exception {
24-
_testParser(JsonRecyclerPools.nonRecyclingPool());
24+
_testParser(JsonRecyclerPools.nonRecyclingPool(), 0, 0);
2525
}
2626

2727
@Test
2828
void parserWithDequeuPool() throws Exception {
29-
_testParser(JsonRecyclerPools.newConcurrentDequePool());
30-
_testParser(JsonRecyclerPools.sharedConcurrentDequePool());
29+
_testParser(JsonRecyclerPools.newConcurrentDequePool(), 0, 1);
30+
_testParser(JsonRecyclerPools.sharedConcurrentDequePool(), null, null);
3131
}
3232

3333
@Test
3434
void parserWithLockFreePool() throws Exception {
35-
_testParser(JsonRecyclerPools.newLockFreePool());
36-
_testParser(JsonRecyclerPools.sharedLockFreePool());
35+
_testParser(JsonRecyclerPools.newLockFreePool(), 0, 1);
36+
_testParser(JsonRecyclerPools.sharedLockFreePool(), null, null);
3737
}
3838

3939
@Test
4040
void parserWithBoundedPool() throws Exception {
41-
_testParser(JsonRecyclerPools.newBoundedPool(5));
42-
_testParser(JsonRecyclerPools.sharedBoundedPool());
41+
_testParser(JsonRecyclerPools.newBoundedPool(5), 0, 1);
42+
_testParser(JsonRecyclerPools.sharedBoundedPool(), null, null);
4343
}
4444

45-
private void _testParser(RecyclerPool<BufferRecycler> pool) throws Exception
45+
private void _testParser(RecyclerPool<BufferRecycler> pool,
46+
Integer expSizeBefore, Integer expSizeAfter) throws Exception
4647
{
4748
JsonFactory jsonF = JsonFactory.builder()
4849
.recyclerPool(pool)
4950
.build();
51+
if (expSizeBefore != null) {
52+
assertEquals(expSizeBefore, pool.pooledCount());
53+
}
5054

5155
JsonParser p = jsonF.createParser(a2q("{'a':123,'b':'foobar'}"));
5256

@@ -62,44 +66,53 @@ private void _testParser(RecyclerPool<BufferRecycler> pool) throws Exception
6266
assertToken(JsonToken.END_OBJECT, p.nextToken());
6367

6468
p.close();
69+
70+
if (expSizeAfter != null) {
71+
assertEquals(expSizeAfter, pool.pooledCount());
72+
}
6573
}
6674

6775
// // Generators with RecyclerPools:
6876

6977
@Test
7078
void generatorWithThreadLocalPool() throws Exception {
71-
_testGenerator(JsonRecyclerPools.threadLocalPool());
79+
_testGenerator(JsonRecyclerPools.threadLocalPool(), -1, -1);
7280
}
7381

7482
@Test
7583
void generatorWithNopLocalPool() throws Exception {
76-
_testGenerator(JsonRecyclerPools.nonRecyclingPool());
84+
_testGenerator(JsonRecyclerPools.nonRecyclingPool(), 0, 0);
7785
}
7886

7987
@Test
8088
void generatorWithDequeuPool() throws Exception {
81-
_testGenerator(JsonRecyclerPools.newConcurrentDequePool());
82-
_testGenerator(JsonRecyclerPools.sharedConcurrentDequePool());
89+
_testGenerator(JsonRecyclerPools.newConcurrentDequePool(), 0, 1);
90+
_testGenerator(JsonRecyclerPools.sharedConcurrentDequePool(), null, null);
8391
}
8492

8593
@Test
8694
void generatorWithLockFreePool() throws Exception {
87-
_testGenerator(JsonRecyclerPools.newLockFreePool());
88-
_testGenerator(JsonRecyclerPools.sharedLockFreePool());
95+
_testGenerator(JsonRecyclerPools.newLockFreePool(), 0, 1);
96+
_testGenerator(JsonRecyclerPools.sharedLockFreePool(), null, null);
8997
}
9098

9199
@Test
92100
void generatorWithBoundedPool() throws Exception {
93-
_testGenerator(JsonRecyclerPools.newBoundedPool(5));
94-
_testGenerator(JsonRecyclerPools.sharedBoundedPool());
101+
_testGenerator(JsonRecyclerPools.newBoundedPool(5), 0, 1);
102+
_testGenerator(JsonRecyclerPools.sharedBoundedPool(), null, null);
95103
}
96-
97-
private void _testGenerator(RecyclerPool<BufferRecycler> pool) throws Exception
104+
105+
private void _testGenerator(RecyclerPool<BufferRecycler> pool,
106+
Integer expSizeBefore, Integer expSizeAfter) throws Exception
98107
{
99108
JsonFactory jsonF = JsonFactory.builder()
100109
.recyclerPool(pool)
101110
.build();
102111

112+
if (expSizeBefore != null) {
113+
assertEquals(expSizeBefore, pool.pooledCount());
114+
}
115+
103116
StringWriter w = new StringWriter();
104117
JsonGenerator g = jsonF.createGenerator(w);
105118

@@ -110,6 +123,10 @@ private void _testGenerator(RecyclerPool<BufferRecycler> pool) throws Exception
110123

111124
g.close();
112125

126+
if (expSizeAfter != null) {
127+
assertEquals(expSizeAfter, pool.pooledCount());
128+
}
129+
113130
assertEquals(a2q("{'a':-42,'b':'barfoo'}"), w.toString());
114131
}
115132

0 commit comments

Comments
 (0)