package com.ctc.wstx.io;

This is a small utility class, whose main functionality is to allow simple reuse of raw byte/char buffers. It is usually used through ThreadLocal member of the owning class pointing to instance of this class through a SoftReference. The end result is a low-overhead GC-cleanable recycling: hopefully ideal for use by stream readers.

Regarding implementation: the key design goal is simplicity; and to that end, different types of buffers are handled separately. While code may look inelegant as a result (wouldn't it be neat to just have generic char[]/byte[] buffer accessors?), benefit is that no data structures are needed, just simple references. As long as usage pattern is well known (which it is, for stream readers) this should be highly optimal and robust implementation.

/** * This is a small utility class, whose main functionality is to allow * simple reuse of raw byte/char buffers. It is usually used through * <code>ThreadLocal</code> member of the owning class pointing to * instance of this class through a <code>SoftReference</code>. The * end result is a low-overhead GC-cleanable recycling: hopefully * ideal for use by stream readers. *<p> * Regarding implementation: the key design goal is simplicity; and to * that end, different types of buffers are handled separately. While * code may look inelegant as a result (wouldn't it be neat to just * have generic char[]/byte[] buffer accessors?), benefit is that * no data structures are needed, just simple references. As long * as usage pattern is well known (which it is, for stream readers) * this should be highly optimal and robust implementation. */
public final class BufferRecycler { private volatile char[] mSmallCBuffer = null; // temp buffers private volatile char[] mMediumCBuffer = null; // text collector private volatile char[] mFullCBuffer = null; // for actual parsing buffer private volatile byte[] mFullBBuffer = null; public BufferRecycler() { } // // // Char buffers: // // Small buffers, for temporary parsing public synchronized char[] getSmallCBuffer(int minSize) { char[] result = mSmallCBuffer; if (result != null && result.length >= minSize) { mSmallCBuffer = null; return result; } //System.err.println("DEBUG: Alloc CSmall: "+result); return null; } public synchronized void returnSmallCBuffer(char[] buffer) { //System.err.println("DEBUG: Return CSmall ("+buffer.length+"): "+buffer); mSmallCBuffer = buffer; } // // Medium buffers, for text output collection public synchronized char[] getMediumCBuffer(int minSize) { char[] result = mMediumCBuffer; if (result != null && result.length >= minSize) { mMediumCBuffer = null; return result; } //System.err.println("DEBUG: Alloc CMed: "+result); return null; } public synchronized void returnMediumCBuffer(char[] buffer) { mMediumCBuffer = buffer; //System.err.println("DEBUG: Return CMed ("+buffer.length+"): "+buffer); } // // Full buffers, for parser buffering public synchronized char[] getFullCBuffer(int minSize) { char[] result = mFullCBuffer; if (result != null && result.length >= minSize) { mFullCBuffer = null; return result; } //System.err.println("DEBUG: Alloc CFull: "+result); return null; } public synchronized void returnFullCBuffer(char[] buffer) { mFullCBuffer = buffer; //System.err.println("DEBUG: Return CFull ("+buffer.length+"): "+buffer); } // // // Byte buffers: // // Full byte buffers, for byte->char conversion (Readers) public synchronized byte[] getFullBBuffer(int minSize) { byte[] result = mFullBBuffer; if (result != null && result.length >= minSize) { mFullBBuffer = null; return result; } //System.err.println("DEBUG: Alloc BFull: "+result); return null; } public synchronized void returnFullBBuffer(byte[] buffer) { mFullBBuffer = buffer; //System.err.println("DEBUG: Return BFull ("+buffer.length+"): "+buffer); } }