Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1114: make BufferRecyclerPool generic #1115

Merged
merged 7 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/com/fasterxml/jackson/core/JsonFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public static int collectDefaults() {
/**
* @since 2.16
*/
protected BufferRecyclerPool _bufferRecyclerPool;
protected BufferRecyclerPool<BufferRecycler> _bufferRecyclerPool;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will probably consider renaming of BufferRecyclerPool as it'll allow recycling other things, but initially leaving name as-is to simplify merging to master.


/**
* Object that implements conversion functionality between
Expand Down Expand Up @@ -2159,7 +2159,7 @@ public BufferRecycler _getBufferRecycler()
*
* @since 2.16
*/
public BufferRecyclerPool _getBufferRecyclerPool() {
public BufferRecyclerPool<BufferRecycler> _getBufferRecyclerPool() {
// 23-Apr-2015, tatu: Let's allow disabling of buffer recycling
// scheme, for cases where it is considered harmful (possibly
// on Android, for example)
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/com/fasterxml/jackson/core/TSFBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.fasterxml.jackson.core.io.OutputDecorator;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.core.json.JsonWriteFeature;
import com.fasterxml.jackson.core.util.BufferRecycler;
import com.fasterxml.jackson.core.util.BufferRecyclerPool;
import com.fasterxml.jackson.core.util.JsonGeneratorDecorator;

Expand Down Expand Up @@ -74,7 +75,7 @@ public abstract class TSFBuilder<F extends JsonFactory,
/**
* @since 2.16
*/
protected BufferRecyclerPool _bufferRecyclerPool;
protected BufferRecyclerPool<BufferRecycler> _bufferRecyclerPool;

/**
* Optional helper object that may decorate input sources, to do
Expand Down Expand Up @@ -169,7 +170,7 @@ protected static <T> List<T> _copy(List<T> src) {
public int streamReadFeatures() { return _streamReadFeatures; }
public int streamWriteFeatures() { return _streamWriteFeatures; }

public BufferRecyclerPool bufferRecyclerPool() {
public BufferRecyclerPool<BufferRecycler> bufferRecyclerPool() {
return _bufferRecyclerPool;
}

Expand Down Expand Up @@ -321,7 +322,7 @@ public B configure(JsonWriteFeature f, boolean state) {
*
* @since 2.16
*/
public B bufferRecyclerPool(BufferRecyclerPool p) {
public B bufferRecyclerPool(BufferRecyclerPool<BufferRecycler> p) {
_bufferRecyclerPool = Objects.requireNonNull(p);
return _this();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* Rewritten in 2.16 to work with {@link BufferRecyclerPool} abstraction.
*/
public class BufferRecycler
implements BufferRecyclerPool.WithPool<BufferRecycler>
{
/**
* Buffer used for reading byte-based input.
Expand Down Expand Up @@ -86,7 +87,7 @@ public class BufferRecycler
// Note: changed from simple array in 2.10:
protected final AtomicReferenceArray<char[]> _charBuffers;

private BufferRecyclerPool _pool;
private BufferRecyclerPool<BufferRecycler> _pool;

/*
/**********************************************************
Expand Down Expand Up @@ -202,7 +203,8 @@ protected int charBufferLength(int ix) {
*
* @since 2.16
*/
BufferRecycler withPool(BufferRecyclerPool pool) {
@Override
public BufferRecycler withPool(BufferRecyclerPool<BufferRecycler> pool) {
if (this._pool != null) {
throw new IllegalStateException("BufferRecycler already linked to pool: "+pool);
}
Expand All @@ -220,7 +222,7 @@ BufferRecycler withPool(BufferRecyclerPool pool) {
*/
public void release() {
if (_pool != null) {
BufferRecyclerPool tmpPool = _pool;
BufferRecyclerPool<BufferRecycler> tmpPool = _pool;
// nullify the reference to the pool in order to avoid the risk of releasing
// the same BufferRecycler more than once, thus compromising the pool integrity
_pool = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@
*
* @since 2.16
*/
public interface BufferRecyclerPool extends Serializable
public interface BufferRecyclerPool<P extends BufferRecyclerPool.WithPool<P>> extends Serializable
{
public interface WithPool<P extends WithPool<P>> {
P withPool(BufferRecyclerPool<P> pool);
}

/**
* Method called to acquire a {@link BufferRecycler} from this pool
* AND make sure it is linked back to this
Expand All @@ -51,15 +55,15 @@ public interface BufferRecyclerPool extends Serializable
* @return {@link BufferRecycler} for caller to use; caller expected
* to call {@link #releaseBufferRecycler} after it is done using recycler.
*/
default BufferRecycler acquireAndLinkBufferRecycler() {
default P acquireAndLinkBufferRecycler() {
return acquireBufferRecycler().withPool(this);
}

/**
* Method for sub-classes to implement for actual acquire logic; called
* by {@link #acquireAndLinkBufferRecycler()}.
*/
BufferRecycler acquireBufferRecycler();
P acquireBufferRecycler();

/**
* Method that should be called when previously acquired (see {@link #acquireAndLinkBufferRecycler})
Expand All @@ -68,30 +72,30 @@ default BufferRecycler acquireAndLinkBufferRecycler() {
*
* @param recycler
*/
void releaseBufferRecycler(BufferRecycler recycler);
void releaseBufferRecycler(P recycler);

/**
* @return the default {@link BufferRecyclerPool} implementation
* which is the thread local based one:
* basically alias to {@link #threadLocalPool()}).
*/
static BufferRecyclerPool defaultPool() {
static BufferRecyclerPool<BufferRecycler> defaultPool() {
return threadLocalPool();
}

/**
* @return Globally shared instance of {@link ThreadLocalPool}; same as calling
* {@link ThreadLocalPool#shared()}.
*/
static BufferRecyclerPool threadLocalPool() {
static BufferRecyclerPool<BufferRecycler> threadLocalPool() {
return ThreadLocalPool.shared();
}

/**
* @return Globally shared instance of {@link NonRecyclingPool}; same as calling
* {@link NonRecyclingPool#shared()}.
*/
static BufferRecyclerPool nonRecyclingPool() {
static BufferRecyclerPool<BufferRecycler> nonRecyclingPool() {
return NonRecyclingPool.shared();
}

Expand All @@ -112,11 +116,11 @@ static BufferRecyclerPool nonRecyclingPool() {
* Android), or on platforms where {@link java.lang.Thread}s are not
* long-living or reused (like Project Loom).
*/
class ThreadLocalPool implements BufferRecyclerPool
class ThreadLocalPool implements BufferRecyclerPool<BufferRecycler>
{
private static final long serialVersionUID = 1L;

private static final BufferRecyclerPool GLOBAL = new ThreadLocalPool();
private static final ThreadLocalPool GLOBAL = new ThreadLocalPool();

/**
* Accessor for the global, shared instance of {@link ThreadLocal}-based
Expand All @@ -125,7 +129,7 @@ class ThreadLocalPool implements BufferRecyclerPool
*
* @return Shared pool instance
*/
public static BufferRecyclerPool shared() {
public static ThreadLocalPool shared() {
return GLOBAL;
}

Expand Down Expand Up @@ -160,11 +164,11 @@ public void releaseBufferRecycler(BufferRecycler recycler) {
* {@link BufferRecyclerPool} implementation that does not use
* any pool but simply creates new instances when necessary.
*/
class NonRecyclingPool implements BufferRecyclerPool
class NonRecyclingPool implements BufferRecyclerPool<BufferRecycler>
{
private static final long serialVersionUID = 1L;

private static final BufferRecyclerPool GLOBAL = new NonRecyclingPool();
private static final NonRecyclingPool GLOBAL = new NonRecyclingPool();

// No instances beyond shared one should be constructed
private NonRecyclingPool() { }
Expand All @@ -175,7 +179,7 @@ private NonRecyclingPool() { }
*
* @return Shared pool instance
*/
public static BufferRecyclerPool shared() {
public static NonRecyclingPool shared() {
return GLOBAL;
}

Expand Down Expand Up @@ -208,7 +212,8 @@ public void releaseBufferRecycler(BufferRecycler recycler) {
* special handling with respect to JDK serialization, to retain
* "global" reference distinct from non-shared ones.
*/
public abstract static class StatefulImplBase implements BufferRecyclerPool
public abstract static class StatefulImplBase<P extends WithPool<P>>
implements BufferRecyclerPool<P>
{
private static final long serialVersionUID = 1L;

Expand All @@ -227,7 +232,7 @@ protected StatefulImplBase(int serialization) {
_serialization = serialization;
}

protected Optional<BufferRecyclerPool> _resolveToShared(BufferRecyclerPool shared) {
protected Optional<StatefulImplBase<P>> _resolveToShared(StatefulImplBase<P> shared) {
if (_serialization == SERIALIZATION_SHARED) {
return Optional.of(shared);
}
Expand All @@ -241,7 +246,7 @@ protected Optional<BufferRecyclerPool> _resolveToShared(BufferRecyclerPool share
*<p>
* Pool is unbounded: see {@link BufferRecyclerPool} what this means.
*/
class ConcurrentDequePool extends StatefulImplBase
class ConcurrentDequePool extends StatefulImplBase<BufferRecycler>
{
private static final long serialVersionUID = 1L;

Expand Down Expand Up @@ -308,7 +313,7 @@ protected Object readResolve() {
* Pool is unbounded: see {@link BufferRecyclerPool} for
* details on what this means.
*/
class LockFreePool extends StatefulImplBase
class LockFreePool extends StatefulImplBase<BufferRecycler>
{
private static final long serialVersionUID = 1L;

Expand Down Expand Up @@ -405,7 +410,7 @@ private static class Node {
* {@link BufferRecycler} instances than its size configuration:
* the default size is {@link BoundedPool#DEFAULT_CAPACITY}.
*/
class BoundedPool extends StatefulImplBase
class BoundedPool extends StatefulImplBase<BufferRecycler>
{
private static final long serialVersionUID = 1L;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.fasterxml.jackson.core.util;

import com.fasterxml.jackson.core.JsonFactory;

/**
* Set of {@link BufferRecyclerPool} implementations to be used by the default
* JSON-backed {@link JsonFactory} for recycling {@link BufferRecycler}
* containers.
*
* @since 2.16
*/
public final class JsonBufferRecyclerPools
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will move BufferRecycler-bound implementations here next.

{

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public void testPluggingPool() throws Exception {
checkBufferRecyclerPoolImpl(new TestPool(), true);
}

private void checkBufferRecyclerPoolImpl(BufferRecyclerPool pool, boolean checkPooledResource) throws Exception {
private void checkBufferRecyclerPoolImpl(BufferRecyclerPool<BufferRecycler> pool,
boolean checkPooledResource) throws Exception {
JsonFactory jsonFactory = JsonFactory.builder()
.bufferRecyclerPool(pool)
.build();
Expand Down Expand Up @@ -82,7 +83,7 @@ private static class NopOutputStream extends OutputStream {


@SuppressWarnings("serial")
class TestPool implements BufferRecyclerPool
class TestPool implements BufferRecyclerPool<BufferRecycler>
{
private BufferRecycler bufferRecycler;

Expand Down