Interface BufferedEncodedOutput

All Superinterfaces:
AutoCloseable, Output<RuntimeException>, Output.CloseableEncodedOutput<RuntimeException>, Output.EncodedOutput<RuntimeException>
All Known Subinterfaces:
ByteBufferEncodedOutput, ChunkEncodedOutput<T>
All Known Implementing Classes:
ByteBufferedOutputStream

public sealed interface BufferedEncodedOutput extends Output.CloseableEncodedOutput<RuntimeException> permits ChunkEncodedOutput<T>, ByteBufferEncodedOutput
An encoded output that will store the output in its preferred memory structure and can then be copied to an OutputStream or read from a ReadableByteChannel. The total size() of the output can also be retrieved before being copied which is useful for setting "Content-Length" HTTP header or for allocating buffers.

The major impetus for this interface is needing the length of the output prior to outputing. If the length is not needed before writing then better performance and memory savings can probably be had by just using Output.EncodedOutput.of(OutputStream, Charset).

In general instances will be empty and not have correct results till Template.EncodedTemplate.write(Object, EncodedOutput) is called.

Currently there are two approaches to buffered output:

  • ByteBufferEncodedOutput: according to benchmarks on most platforms other than Windows it is more CPU friendly but less memory friendly. It is ideal for platforms where you can return ByteBuffer directly or need to return a byte[]. The default implementation uses a growing array and can be created with ByteBufferEncodedOutput.ofByteArray(Charset, int) and can be reused provided close() is called. Reuse can be useful if using ThreadLocals or some other pooling mechanism.
  • ChunkEncodedOutput: according to benchmarks is more optimized for memory savings as well as possible reduction of copying. This approach originated from Rocker's purported "near zero copy".
Regardless one should benchmark each approach to determine which one best fits for their platform. In many cases a custom Output.EncodedOutput that uses the platform's underlying buffer pool will probably yield the best results.
Author:
agentgt
See Also:
API Note
Methods starting with "as" are a view where as methods starting with "to" (or ending in "To" for the case of transferTo) are a copy. If the output is to be reused "as" methods should be copied or fully used before the output is reused.
  • Method Details

    • size

      int size()
      Total size in number of bytes of the output.
      Returns:
      size
      See Also:
    • transferTo

      default void transferTo(OutputStream stream) throws IOException
      Transfers the entire buffered output by writing to an OutputStream.
      Parameters:
      stream - not null and will not be closed or flushed.
      Throws:
      IOException - if the stream throws an IOException.
      See Also:
      API Note
      For nonblocking asReadableByteChannel() is generally accepted as the better aproach as it is a pull model.
    • limit

      Decorates this buffer so that buffering is limited to certain amount and will eventually send all output to the OutputStream created by the factory. The factory will be passed -1 if the limit is exceeded and create will only be called once and only once provided that the returned object is closed.

      This method should be called before passed to JStachio and the result is the output that should be passed.

      Parameters:
      limit - the maximum amount of bytes to buffer.
      factory - create the output stream on demand and will always be used before close is called.
      Returns:
      output that will need to be closed eventually.
      See Also:
    • accept

      <E extends Exception> void accept(OutputConsumer<E> consumer) throws E
      Transfers the entire buffered output to a consumer
      Type Parameters:
      E - the exception type
      Parameters:
      consumer - not null.
      Throws:
      E - if the consumer throws an exception
      See Also:
      API Note
      For nonblocking asReadableByteChannel() is generally accepted as the better aproach as it is a pull model.
    • bufferSizeHint

      default int bufferSizeHint()
      The recommend buffer size to use for extracting with asReadableByteChannel() or transferTo(OutputStream).
      Returns:
      buffer size to use which by default is size().
    • asReadableByteChannel

      ReadableByteChannel asReadableByteChannel()
      Represents the encoded output as readable channel. The channel should be closed when finished to signal reuse or destruction of the buffered output!. To possibly help determine the buffer to use for ReadableByteChannel.read(java.nio.ByteBuffer) one can use bufferSizeHint() or size().
      Returns:
      channel open and ready to read from at the start of the output.
      See Also:
    • toByteArray

      default byte[] toByteArray()
      Copies the output to a byte array.
      Returns:
      a copied byte array of the output
    • append

      default void append(String s)
      Description copied from interface: Output
      Analogous to Appendable.append(CharSequence) which by default treats the String as a CharSequence.
      Specified by:
      append in interface Output<RuntimeException>
      Specified by:
      append in interface Output.EncodedOutput<RuntimeException>
      Parameters:
      s - unlike appendable always non null.
    • append

      default void append(CharSequence s)
      Description copied from interface: Output
      Specified by:
      append in interface Output<RuntimeException>
      Parameters:
      s - unlike appendable always non null.
    • close

      void close()
      Signals that the buffer should be reset for reuse or destroyed.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Output.CloseableEncodedOutput<RuntimeException>
      API Note
      This does not throw an IOException on purpose since everything is in memory.
    • isReusable

      default boolean isReusable()
      If this instance can be reused after close() is called.
      Returns:
      true if reuse is allowed by default false is returned.
    • ofChunked

      static BufferedEncodedOutput ofChunked(Charset charset)
      Create a buffered encoded output backed by a sequence of chunks.
      Parameters:
      charset - the expected encoding
      Returns:
      buffered output