Skip to content

Commit

Permalink
Fix #403: remove SmileBufferRecycler from 2.16 (#404)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Oct 4, 2023
1 parent 6e59271 commit 200ee04
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 274 deletions.
4 changes: 4 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Active maintainers:
=== Releases ===
------------------------------------------------------------------------

2.16.0 (not yet released)

#403: Remove Smile-specific buffer-recycling

2.15.3 (not yet released)

#384: `Smile` decoding issue with `NonBlockingByteArrayParser`, concurrency
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,6 @@ public class SmileFactory extends JsonFactory
protected int _smileParserFeatures;
protected int _smileGeneratorFeatures;

/*
/**********************************************************
/* Smile-specific buffer recycling (moved here in 2.16)
/**********************************************************
/**
* This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftReference}
* to a buffer recycler used to provide a low-cost
* buffer recycling for Smile-specific buffers.
*/
final protected static ThreadLocal<SoftReference<SmileBufferRecycler>> _smileRecyclerRef
= new ThreadLocal<SoftReference<SmileBufferRecycler>>();

/*
/**********************************************************
/* Factory construction, configuration
Expand Down Expand Up @@ -429,8 +416,7 @@ public NonBlockingByteArrayParser createNonBlockingByteArrayParser() throws IOEx
// 13-Mar-2021, tatu: [dataformats-binary#252] Leave async parser with
// always-canonicalizing, for now (2.13) -- to be improved in future
ByteQuadsCanonicalizer can = _byteSymbolCanonicalizer.makeChildOrPlaceholder(_factoryFeatures);
return new NonBlockingByteArrayParser(ctxt, _parserFeatures, _smileParserFeatures, can,
_smileBufferRecycler());
return new NonBlockingByteArrayParser(ctxt, _parserFeatures, _smileParserFeatures, can);
}

/*
Expand All @@ -447,8 +433,7 @@ protected SmileParser _createParser(InputStream in, IOContext ctxt) throws IOExc
{
SmileParserBootstrapper bs = new SmileParserBootstrapper(ctxt, in);
return bs.constructParser(_factoryFeatures, _parserFeatures,
_smileParserFeatures, _objectCodec, _byteSymbolCanonicalizer,
_smileBufferRecycler());
_smileParserFeatures, _objectCodec, _byteSymbolCanonicalizer);
}

@Override
Expand All @@ -475,8 +460,7 @@ protected SmileParser _createParser(byte[] data, int offset, int len, IOContext
{
return new SmileParserBootstrapper(ctxt, data, offset, len).constructParser(
_factoryFeatures, _parserFeatures, _smileParserFeatures,
_objectCodec, _byteSymbolCanonicalizer,
_smileBufferRecycler());
_objectCodec, _byteSymbolCanonicalizer);
}

@Override
Expand Down Expand Up @@ -526,8 +510,7 @@ protected SmileGenerator _createGenerator(OutputStream out, IOContext ctxt) thro
* But should we force writing, or throw exception, if settings are in conflict?
* For now, let's error out...
*/
SmileGenerator gen = new SmileGenerator(ctxt, _generatorFeatures, feats, _objectCodec, out,
_smileBufferRecycler());
SmileGenerator gen = new SmileGenerator(ctxt, _generatorFeatures, feats, _objectCodec, out);
if ((feats & SmileGenerator.Feature.WRITE_HEADER.getMask()) != 0) {
gen.writeHeader();
} else {
Expand All @@ -546,16 +529,4 @@ protected SmileGenerator _createGenerator(OutputStream out, IOContext ctxt) thro
}
return gen;
}

protected final static SmileBufferRecycler _smileBufferRecycler()
{
SoftReference<SmileBufferRecycler> ref = _smileRecyclerRef.get();
SmileBufferRecycler br = (ref == null) ? null : ref.get();

if (br == null) {
br = new SmileBufferRecycler();
_smileRecyclerRef.set(new SoftReference<SmileBufferRecycler>(br));
}
return br;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
public class SmileGenerator
extends GeneratorBase
{
// @since 2.16
protected final static int DEFAULT_NAME_BUFFER_LENGTH = 64;

// @since 2.16
protected final static int DEFAULT_STRING_VALUE_BUFFER_LENGTH = 64;

/**
* Enumeration that defines all togglable features for Smile generators.
*/
Expand Down Expand Up @@ -196,12 +202,6 @@ public SharedStringNode(String value, int index, SharedStringNode next)
*/
protected int _formatFeatures;

/**
* Helper object used for low-level recycling of Smile-generator
* specific buffers.
*/
protected final SmileBufferRecycler _smileBufferRecycler;

/*
/**********************************************************************
/* Output state
Expand Down Expand Up @@ -288,8 +288,7 @@ public SharedStringNode(String value, int index, SharedStringNode next)
* @since 2.16
*/
public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
ObjectCodec codec, OutputStream out,
SmileBufferRecycler sbr)
ObjectCodec codec, OutputStream out)
{
super(stdFeatures, codec, ioCtxt, /*WriteContext*/ null);
DupDetector dups = JsonGenerator.Feature.STRICT_DUPLICATE_DETECTION.enabledIn(stdFeatures)
Expand All @@ -299,7 +298,6 @@ public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
_streamWriteContext = SmileWriteContext.createRootContext(dups);
_formatFeatures = smileFeatures;
_streamWriteConstraints = ioCtxt.streamWriteConstraints();
_smileBufferRecycler = sbr;
_out = out;
_bufferRecyclable = true;
_outputBuffer = ioCtxt.allocWriteEncodingBuffer();
Expand All @@ -314,21 +312,15 @@ public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
_seenNames = null;
_seenNameCount = -1;
} else {
_seenNames = _smileBufferRecycler.allocSeenNamesWriteBuffer();
if (_seenNames == null) {
_seenNames = new SharedStringNode[SmileBufferRecycler.DEFAULT_NAME_BUFFER_LENGTH];
}
_seenNames = new SharedStringNode[DEFAULT_NAME_BUFFER_LENGTH];
_seenNameCount = 0;
}

if (!Feature.CHECK_SHARED_STRING_VALUES.enabledIn(smileFeatures)) {
_seenStringValues = null;
_seenStringValueCount = -1;
} else {
_seenStringValues = _smileBufferRecycler.allocSeenStringValuesWriteBuffer();
if (_seenStringValues == null) {
_seenStringValues = new SharedStringNode[SmileBufferRecycler.DEFAULT_STRING_VALUE_BUFFER_LENGTH];
}
_seenStringValues = new SharedStringNode[DEFAULT_STRING_VALUE_BUFFER_LENGTH];
_seenStringValueCount = 0;
}
}
Expand All @@ -338,7 +330,6 @@ public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
*/
public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
ObjectCodec codec, OutputStream out,
SmileBufferRecycler sbr,
byte[] outputBuffer, int offset, boolean bufferRecyclable)
{
super(stdFeatures, codec, ioCtxt, null);
Expand All @@ -349,7 +340,6 @@ public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
_streamWriteContext = SmileWriteContext.createRootContext(dups);
_formatFeatures = smileFeatures;
_streamWriteConstraints = ioCtxt.streamWriteConstraints();
_smileBufferRecycler = sbr;
_out = out;
_bufferRecyclable = bufferRecyclable;
_outputTail = offset;
Expand All @@ -365,48 +355,19 @@ public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
_seenNames = null;
_seenNameCount = -1;
} else {
_seenNames = _smileBufferRecycler.allocSeenNamesWriteBuffer();
if (_seenNames == null) {
_seenNames = new SharedStringNode[SmileBufferRecycler.DEFAULT_NAME_BUFFER_LENGTH];
}
_seenNames = new SharedStringNode[DEFAULT_NAME_BUFFER_LENGTH];
_seenNameCount = 0;
}

if (!Feature.CHECK_SHARED_STRING_VALUES.enabledIn(smileFeatures)) {
_seenStringValues = null;
_seenStringValueCount = -1;
} else {
_seenStringValues = _smileBufferRecycler.allocSeenStringValuesWriteBuffer();
if (_seenStringValues == null) {
_seenStringValues = new SharedStringNode[SmileBufferRecycler.DEFAULT_STRING_VALUE_BUFFER_LENGTH];
}
_seenStringValues = new SharedStringNode[DEFAULT_STRING_VALUE_BUFFER_LENGTH];
_seenStringValueCount = 0;
}
}

/**
* @deprecated Since 2.16
*/
@Deprecated // @since 2.16
public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
ObjectCodec codec, OutputStream out)
{
this(ioCtxt, stdFeatures, smileFeatures, codec, out, new SmileBufferRecycler());
}

/**
* @deprecated Since 2.16
*/
@Deprecated // @since 2.16
public SmileGenerator(IOContext ioCtxt, int stdFeatures, int smileFeatures,
ObjectCodec codec, OutputStream out,
byte[] outputBuffer, int offset, boolean bufferRecyclable)
{
this(ioCtxt, stdFeatures, smileFeatures,
codec, out, new SmileBufferRecycler(),
outputBuffer, offset, bufferRecyclable);
}

/**
* Method that can be called to explicitly write Smile document header.
* Note that usually you do not need to call this for first document to output,
Expand Down Expand Up @@ -2629,35 +2590,6 @@ protected void _releaseBuffers()
_outputBuffer = null;
_ioContext.releaseWriteEncodingBuffer(buf);
}
/* Ok: since clearing up of larger arrays is much slower,
* let's only recycle default-sized buffers...
*/
{
SharedStringNode[] nameBuf = _seenNames;
if (nameBuf != null && nameBuf.length == SmileBufferRecycler.DEFAULT_NAME_BUFFER_LENGTH) {
_seenNames = null;
/* 28-Jun-2011, tatu: With 1.9, caller needs to clear the buffer; and note
* that since it's a hash area, must clear all
*/
if (_seenNameCount > 0) {
Arrays.fill(nameBuf, null);
}
_smileBufferRecycler.releaseSeenNamesWriteBuffer(nameBuf);
}
}
{
SharedStringNode[] valueBuf = _seenStringValues;
if (valueBuf != null && valueBuf.length == SmileBufferRecycler.DEFAULT_STRING_VALUE_BUFFER_LENGTH) {
_seenStringValues = null;
/* 28-Jun-2011, tatu: With 1.9, caller needs to clear the buffer; and note
* that since it's a hash area, must clear all
*/
if (_seenStringValueCount > 0) {
Arrays.fill(valueBuf, null);
}
_smileBufferRecycler.releaseSeenStringValuesWriteBuffer(valueBuf);
}
}
}

protected final void _flushBuffer() throws IOException
Expand Down

0 comments on commit 200ee04

Please sign in to comment.