Class DynamicOutputBuffer

java.lang.Object
de.undercouch.bson4jackson.io.DynamicOutputBuffer

public class DynamicOutputBuffer extends Object

A random-access buffer that resizes itself. This buffer differentiates from ByteArrayOutputStream in the following points:

  • It allows specifying the byte order.
  • It assigns several internal buffers instead of one and therefore saves garbage collection cycles.
  • It is able to flush some of its internal buffers to an output stream or to a writable channel.

The buffer has an initial size. This is also the size of each internal buffer, so if a new buffer has to be allocated it will take exactly that many bytes.

By calling flushTo(OutputStream) or flushTo(WritableByteChannel) some of this buffer's internal buffers are flushed and then deallocated. The buffer maintains an internal counter for all flushed buffers. This allows the writeTo(OutputStream) and writeTo(WritableByteChannel) methods to only write non-flushed buffers. So, this class can be used for streaming by flushing internal buffers from time to time and at the end writing the rest:

 ...
 buf.flushTo(out);
 ...
 buf.flushTo(out);
 ...
 buf.flushTo(out);
 ...
 buf.writeTo(out);

If flushing is never used a single call to one of the writeTo methods is enough to write the whole buffer.

Once the buffer has been written to an output stream or channel, putting elements into it is not possible anymore and will lead to an IndexOutOfBoundsException.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected List<ByteBuffer>
    A linked list of internal buffers
    protected final int
    The size of each internal buffer (also the initial buffer size)
    protected Queue<ByteBuffer>
    A queue of buffers that have already been flushed and are free to reuse.
    protected int
    The position of the first byte that has not been already flushed.
    protected final ByteOrder
    The byte order of this buffer
    protected int
    The current write position
    protected int
    The number of buffers to reuse
    protected int
    The current buffer size (changes dynamically)
    protected static final StaticBuffers.Key
    A unique key to make the first buffer re-usable
    static final int
    The default initial buffer size if nothing is specified
    static final ByteOrder
    The default byte order if nothing is specified
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates a dynamic buffer with BIG_ENDIAN byte order and a default initial buffer size of DEFAULT_BUFFER_SIZE bytes.
    DynamicOutputBuffer(int initialSize)
    Creates a dynamic buffer with BIG_ENDIAN byte order and the given initial buffer size.
    Creates a dynamic buffer with the given byte order and a default initial buffer size of DEFAULT_BUFFER_SIZE bytes.
    DynamicOutputBuffer(ByteOrder order, int initialSize)
    Creates a dynamic buffer with the given byte order and the given initial buffer size.
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    adaptSize(int size)
    Adapts the buffer size so it is at least equal to the given number of bytes.
    protected ByteBuffer
    Adds a new buffer to the list of internal buffers
    protected ByteBuffer
    Allocates a new buffer or attempts to reuse an existing one.
    void
    Clear the buffer and reset size and write position
    protected void
    Removes a buffer from the list of internal buffers and saves it for reuse if this feature is enabled.
    void
    Tries to copy as much bytes as possible from this buffer to the given channel.
    void
    Tries to copy as much bytes as possible from this buffer to the given channel.
    protected ByteBuffer
    getBuffer(int position)
    Gets the buffer that holds the byte at the given absolute position.
    void
    putByte(byte b)
    Puts a byte into the buffer at the current write position and increases the write position accordingly.
    void
    putByte(int pos, byte b)
    Puts a byte into the buffer at the given position.
    void
    putBytes(byte... bs)
    Puts several bytes into the buffer at the given position and increases the write position accordingly.
    void
    putBytes(byte[] bs, int offset, int length)
    Puts a byte array into the buffer at the given position with the given offset and increases the write position accordingly.
    void
    putBytes(int pos, byte... bs)
    Puts several bytes into the buffer at the given position.
    void
    putBytes(int pos, byte[] bs, int offset, int length)
    Puts a byte array into the buffer at the given position with the given offset.
    void
    putDouble(double d)
    Puts a 64-bit floating point number into the buffer at the current write position and increases the write position accordingly.
    void
    putDouble(int pos, double d)
    Puts a 64-bit floating point number into the buffer at the given position.
    void
    putFloat(float f)
    Puts a 32-bit floating point number into the buffer at the current write position and increases the write position accordingly.
    void
    putFloat(int pos, float f)
    Puts a 32-bit floating point number into the buffer at the given position.
    void
    putInt(int i)
    Puts a 32-bit integer into the buffer at the current write position and increases write position accordingly.
    void
    putInt(int pos, int i)
    Puts a 32-bit integer into the buffer at the given position.
    void
    putLong(int pos, long l)
    Puts a 64-bit integer into the buffer at the given position.
    void
    putLong(long l)
    Puts a 64-bit integer into the buffer at the current write position and increases the write position accordingly.
    void
    putString(int pos, CharSequence s)
    Puts a character sequence into the buffer at the given position.
    void
    Puts a character sequence into the buffer at the current write position and increases the write position accordingly.
    int
    putUTF8(int pos, String s)
    Puts the given string as UTF-8 into the buffer at the given position.
    int
    Encodes the given string as UTF-8, puts it into the buffer and increases the write position accordingly.
    void
    Sets the number of buffers to save for reuse after they have been invalidated by flushTo(OutputStream) or flushTo(WritableByteChannel).
    int
     
    void
    Writes all non-flushed internal buffers to the given output stream.
    void
    Writes all non-flushed internal buffers to the given channel.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • DEFAULT_BYTE_ORDER

      public static final ByteOrder DEFAULT_BYTE_ORDER
      The default byte order if nothing is specified
    • BUFFER_KEY

      protected static final StaticBuffers.Key BUFFER_KEY
      A unique key to make the first buffer re-usable
    • DEFAULT_BUFFER_SIZE

      public static final int DEFAULT_BUFFER_SIZE
      The default initial buffer size if nothing is specified
    • _order

      protected final ByteOrder _order
      The byte order of this buffer
    • _bufferSize

      protected final int _bufferSize
      The size of each internal buffer (also the initial buffer size)
    • _position

      protected int _position
      The current write position
    • _flushPosition

      protected int _flushPosition
      The position of the first byte that has not been already flushed. Any attempt to put something into the buffer at a position before this first byte is invalid and causes a IndexOutOfBoundsException to be thrown.
    • _size

      protected int _size
      The current buffer size (changes dynamically)
    • _buffers

      protected List<ByteBuffer> _buffers
      A linked list of internal buffers
    • _buffersToReuse

      protected Queue<ByteBuffer> _buffersToReuse
      A queue of buffers that have already been flushed and are free to reuse.
      See Also:
    • _reuseBuffersCount

      protected int _reuseBuffersCount
      The number of buffers to reuse
      See Also:
  • Constructor Details

    • DynamicOutputBuffer

      public DynamicOutputBuffer()
      Creates a dynamic buffer with BIG_ENDIAN byte order and a default initial buffer size of DEFAULT_BUFFER_SIZE bytes.
    • DynamicOutputBuffer

      public DynamicOutputBuffer(int initialSize)
      Creates a dynamic buffer with BIG_ENDIAN byte order and the given initial buffer size.
      Parameters:
      initialSize - the initial buffer size
    • DynamicOutputBuffer

      public DynamicOutputBuffer(ByteOrder order)
      Creates a dynamic buffer with the given byte order and a default initial buffer size of DEFAULT_BUFFER_SIZE bytes.
      Parameters:
      order - the byte order
    • DynamicOutputBuffer

      public DynamicOutputBuffer(ByteOrder order, int initialSize)
      Creates a dynamic buffer with the given byte order and the given initial buffer size.
      Parameters:
      order - the byte order
      initialSize - the initial buffer size
  • Method Details

    • setReuseBuffersCount

      public void setReuseBuffersCount(int count)
      Sets the number of buffers to save for reuse after they have been invalidated by flushTo(OutputStream) or flushTo(WritableByteChannel). Invalidated buffers will be saved in an internal queue. When the buffer needs a new internal buffer, it first attempts to reuse an existing one before allocating a new one.
      Parameters:
      count - the number of buffers to save for reuse
    • allocateBuffer

      protected ByteBuffer allocateBuffer()
      Allocates a new buffer or attempts to reuse an existing one.
      Returns:
      a new buffer with the current buffer size and the current byte order
    • deallocateBuffer

      protected void deallocateBuffer(int n)
      Removes a buffer from the list of internal buffers and saves it for reuse if this feature is enabled.
      Parameters:
      n - the number of the buffer to remove
    • addNewBuffer

      protected ByteBuffer addNewBuffer()
      Adds a new buffer to the list of internal buffers
      Returns:
      the new buffer
    • getBuffer

      protected ByteBuffer getBuffer(int position)
      Gets the buffer that holds the byte at the given absolute position. Automatically adds new internal buffers if the position lies outside the current range of all internal buffers.
      Parameters:
      position - the position
      Returns:
      the buffer at the requested position
    • adaptSize

      protected void adaptSize(int size)
      Adapts the buffer size so it is at least equal to the given number of bytes. This method does not add new internal buffers.
      Parameters:
      size - the minimum buffer size
    • size

      public int size()
      Returns:
      the current buffer size (changes dynamically)
    • clear

      public void clear()
      Clear the buffer and reset size and write position
    • putByte

      public void putByte(byte b)
      Puts a byte into the buffer at the current write position and increases the write position accordingly.
      Parameters:
      b - the byte to put
    • putBytes

      public void putBytes(byte... bs)
      Puts several bytes into the buffer at the given position and increases the write position accordingly.
      Parameters:
      bs - an array of bytes to put
    • putBytes

      public void putBytes(byte[] bs, int offset, int length)
      Puts a byte array into the buffer at the given position with the given offset and increases the write position accordingly.
      Parameters:
      bs - an array of bytes to put
      offset - the offset within the array of the first byte to be read
      length - the number of bytes to be read from the given array
    • putByte

      public void putByte(int pos, byte b)
      Puts a byte into the buffer at the given position. Does not increase the write position.
      Parameters:
      pos - the position where to put the byte
      b - the byte to put
    • putBytes

      public void putBytes(int pos, byte... bs)
      Puts several bytes into the buffer at the given position. Does not increase the write position.
      Parameters:
      pos - the position where to put the bytes
      bs - an array of bytes to put
    • putBytes

      public void putBytes(int pos, byte[] bs, int offset, int length)
      Puts a byte array into the buffer at the given position with the given offset. Does not increase the write position.
      Parameters:
      pos - the position where to put the bytes
      bs - an array of bytes to put
      offset - the offset within the array of the first byte to be read
      length - the number of bytes to be read from the given array
    • putInt

      public void putInt(int i)
      Puts a 32-bit integer into the buffer at the current write position and increases write position accordingly.
      Parameters:
      i - the integer to put
    • putInt

      public void putInt(int pos, int i)
      Puts a 32-bit integer into the buffer at the given position. Does not increase the write position.
      Parameters:
      pos - the position where to put the integer
      i - the integer to put
    • putLong

      public void putLong(long l)
      Puts a 64-bit integer into the buffer at the current write position and increases the write position accordingly.
      Parameters:
      l - the 64-bit integer to put
    • putLong

      public void putLong(int pos, long l)
      Puts a 64-bit integer into the buffer at the given position. Does not increase the write position.
      Parameters:
      pos - the position where to put the integer
      l - the 64-bit integer to put
    • putFloat

      public void putFloat(float f)
      Puts a 32-bit floating point number into the buffer at the current write position and increases the write position accordingly.
      Parameters:
      f - the float to put
    • putFloat

      public void putFloat(int pos, float f)
      Puts a 32-bit floating point number into the buffer at the given position. Does not increase the write position.
      Parameters:
      pos - the position where to put the float
      f - the float to put
    • putDouble

      public void putDouble(double d)
      Puts a 64-bit floating point number into the buffer at the current write position and increases the write position accordingly.
      Parameters:
      d - the double to put
    • putDouble

      public void putDouble(int pos, double d)
      Puts a 64-bit floating point number into the buffer at the given position. Does not increase the write position.
      Parameters:
      pos - the position where to put the double
      d - the double to put
    • putString

      public void putString(CharSequence s)
      Puts a character sequence into the buffer at the current write position and increases the write position accordingly.
      Parameters:
      s - the character sequence to put
    • putString

      public void putString(int pos, CharSequence s)
      Puts a character sequence into the buffer at the given position. Does not increase the write position.
      Parameters:
      pos - the position where to put the character sequence
      s - the character sequence to put
    • putUTF8

      public int putUTF8(String s)
      Encodes the given string as UTF-8, puts it into the buffer and increases the write position accordingly.
      Parameters:
      s - the string to put
      Returns:
      the number of UTF-8 bytes put
    • putUTF8

      public int putUTF8(int pos, String s)
      Puts the given string as UTF-8 into the buffer at the given position. This method does not increase the write position.
      Parameters:
      pos - the position where to put the string
      s - the string to put
      Returns:
      the number of UTF-8 bytes put
    • flushTo

      public void flushTo(OutputStream out) throws IOException
      Tries to copy as much bytes as possible from this buffer to the given channel. See flushTo(WritableByteChannel) for further information.
      Parameters:
      out - the output stream to write to
      Throws:
      IOException - if the buffer could not be flushed
    • flushTo

      public void flushTo(WritableByteChannel out) throws IOException
      Tries to copy as much bytes as possible from this buffer to the given channel. This method always copies whole internal buffers and deallocates them afterwards. It does not deallocate the buffer the write position is currently pointing to nor does it deallocate buffers following the write position. The method increases an internal pointer so consecutive calls also copy consecutive bytes.
      Parameters:
      out - the channel to write to
      Throws:
      IOException - if the buffer could not be flushed
    • writeTo

      public void writeTo(OutputStream out) throws IOException
      Writes all non-flushed internal buffers to the given output stream. If flushTo(OutputStream) has not been called before, this method writes the whole buffer to the output stream.
      Parameters:
      out - the output stream to write to
      Throws:
      IOException - if the buffer could not be written
    • writeTo

      public void writeTo(WritableByteChannel out) throws IOException
      Writes all non-flushed internal buffers to the given channel. If flushTo(WritableByteChannel) has not been called before, this method writes the whole buffer to the channel.
      Parameters:
      out - the channel to write to
      Throws:
      IOException - if the buffer could not be written