Class BytesStreamOutput

All Implemented Interfaces:
Closeable, Flushable, AutoCloseable
Direct Known Subclasses:
ReleasableBytesStreamOutput

public class BytesStreamOutput extends BytesStream
A @link StreamOutput that accumulates the resulting data in memory, using BigArrays to avoids frequent reallocation & copying of the internal data once the resulting data grows large enough whilst avoiding excessive overhead in the final result for small objects.

A BytesStreamOutput accumulates data using a non-recycling BigArrays and, as with an OutputStreamStreamOutput, it uses a thread-locally-cached buffer for some of its writes and pushes data to the underlying array in small chunks, causing frequent calls to BigArrays.resize(org.elasticsearch.common.util.ByteArray, long). If the array is large enough (≥16kiB) then the resize operations happen in-place, allocating a new 16kiB byte[] and appending it to the array, but for smaller arrays these resize operations allocate a completely fresh byte[] into which they copy the entire contents of the old one.

BigArrays.resize(org.elasticsearch.common.util.ByteArray, long) grows smaller arrays more slowly than a ByteArrayOutputStream, with a target of 12.5% overhead rather than 100%, which means that a sequence of smaller writes causes more allocations and copying overall. It may be worth adding a BufferedStreamOutput wrapper to reduce the frequency of the resize operations, especially if a suitable buffer is already allocated and available.

The resulting BytesReference is a view over the underlying byte[] pages and involves no significant extra allocation to obtain. It is oversized: The worst case for overhead is when the data is one byte more than a 16kiB page and therefore the result must retain two pages even though all but one byte of the second page is unused. For smaller objects the overhead will be 12.5%.

Any memory allocated in this way is untracked by the org.elasticsearch.common.breaker subsystem unless the caller takes steps to add this tracking themselves.