Skip to content

Commit

Permalink
Add skeletal pieces for #400 (not working but need to back up)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Oct 14, 2023
1 parent 4260f58 commit 2177b03
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import com.fasterxml.jackson.core.format.InputAccessor;
import com.fasterxml.jackson.core.format.MatchStrength;
import com.fasterxml.jackson.core.io.IOContext;

import com.fasterxml.jackson.core.util.RecyclerPool;
import com.fasterxml.jackson.dataformat.avro.apacheimpl.ApacheCodecRecycler;
import com.fasterxml.jackson.dataformat.avro.deser.*;

/**
Expand Down Expand Up @@ -40,6 +41,11 @@ public class AvroFactory extends JsonFactory
/**********************************************************
*/

/**
* @since 2.16
*/
protected RecyclerPool<ApacheCodecRecycler> _avroRecyclerPool;

protected int _avroParserFeatures;

protected int _avroGeneratorFeatures;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.fasterxml.jackson.dataformat.avro.apacheimpl;

import java.lang.ref.SoftReference;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

import com.fasterxml.jackson.core.util.RecyclerPool;
import com.fasterxml.jackson.core.util.RecyclerPool.WithPool;

import org.apache.avro.io.*;

/**
Expand All @@ -12,51 +15,73 @@
* @since 2.8.7
*/
public final class ApacheCodecRecycler
implements WithPool<ApacheCodecRecycler>
{
protected final static ThreadLocal<SoftReference<ApacheCodecRecycler>> _recycler
= new ThreadLocal<SoftReference<ApacheCodecRecycler>>();

private final AtomicReference<BinaryDecoder> decoderRef = new AtomicReference<>();
private final AtomicReference<BinaryEncoder> encoderRef = new AtomicReference<>();

private ApacheCodecRecycler() { }
private RecyclerPool<ApacheCodecRecycler> _pool;

ApacheCodecRecycler() { }

/*
/**********************************************************
/* Public API
/**********************************************************
*/

public static BinaryDecoder acquireDecoder() {
return _recycler().decoderRef.getAndSet(null);
public BinaryDecoder acquireDecoder() {
return decoderRef.getAndSet(null);
}

public static BinaryEncoder acquireEncoder() {
return _recycler().encoderRef.getAndSet(null);
public BinaryEncoder acquireEncoder() {
return encoderRef.getAndSet(null);
}

public static void release(BinaryDecoder dec) {
_recycler().decoderRef.set(dec);
public void release(BinaryDecoder dec) {
decoderRef.set(dec);
}

public static void release(BinaryEncoder enc) {
_recycler().encoderRef.set(enc);
public void release(BinaryEncoder enc) {
encoderRef.set(enc);
}

/*
/**********************************************************
/* Internal per-instance methods
/* WithPool implementation
/**********************************************************
*/

/**
* Method called by owner of this recycler instance, to provide reference to
* {@link RecyclerPool} into which instance is to be released (if any)
*
* @since 2.16
*/
@Override
public ApacheCodecRecycler withPool(RecyclerPool<ApacheCodecRecycler> pool) {
if (this._pool != null) {
throw new IllegalStateException("ApacheCodecRecycler already linked to pool: "+pool);
}
// assign to pool to which this BufferRecycler belongs in order to release it
// to the same pool when the work will be completed
_pool = Objects.requireNonNull(pool);
return this;
}

private static ApacheCodecRecycler _recycler() {
SoftReference<ApacheCodecRecycler> ref = _recycler.get();
ApacheCodecRecycler r = (ref == null) ? null : ref.get();

if (r == null) {
r = new ApacheCodecRecycler();
_recycler.set(new SoftReference<>(r));
/**
* Method called when owner of this recycler no longer wishes use it; this should
* return it to pool passed via {@code withPool()} (if any).
*
* @since 2.16
*/
public void release() {
if (_pool != null) {
RecyclerPool<ApacheCodecRecycler> 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;
tmpPool.releasePooled(this);
}
return r;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.fasterxml.jackson.dataformat.avro.apacheimpl;

import java.lang.ref.SoftReference;

import com.fasterxml.jackson.core.util.BufferRecycler;
import com.fasterxml.jackson.core.util.RecyclerPool;

public final class AvroRecyclerPools
{
/**
* @return the default {@link RecyclerPool} implementation
* which is the thread local based one:
* basically alias to {@link #threadLocalPool()}).
*/
public static RecyclerPool<ApacheCodecRecycler> defaultPool() {
return threadLocalPool();
}

/**
* Accessor for getting the shared/global {@link ThreadLocalPool} instance
* (due to design only one instance ever needed)
*
* @return Globally shared instance of {@link ThreadLocalPool}
*/
public static RecyclerPool<ApacheCodecRecycler> threadLocalPool() {
return ThreadLocalPool.GLOBAL;
}

/*
/**********************************************************************
/* Concrete RecyclerPool implementations for recycling BufferRecyclers
/**********************************************************************
*/

/**
* {@link ThreadLocal}-based {@link RecyclerPool} implementation used for
* recycling {@link BufferRecycler} instances:
* see {@link RecyclerPool.ThreadLocalPoolBase} for full explanation
* of functioning.
*/
public static class ThreadLocalPool
extends RecyclerPool.ThreadLocalPoolBase<ApacheCodecRecycler>
{
private static final long serialVersionUID = 1L;

protected static final ThreadLocalPool GLOBAL = new ThreadLocalPool();

protected final static ThreadLocal<SoftReference<ApacheCodecRecycler>> _recycler
= new ThreadLocal<SoftReference<ApacheCodecRecycler>>();

private ThreadLocalPool() { }

@Override
public ApacheCodecRecycler acquirePooled() {
SoftReference<ApacheCodecRecycler> ref = _recycler.get();
ApacheCodecRecycler r = (ref == null) ? null : ref.get();

if (r == null) {
r = new ApacheCodecRecycler();
_recycler.set(new SoftReference<>(r));
}
return r;
}

// // // JDK serialization support

protected Object readResolve() { return GLOBAL; }
}

}

0 comments on commit 2177b03

Please sign in to comment.