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

Lines changed: 55 additions & 6 deletions
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 36 additions & 19 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy