Skip to content

Allow Encoder to use ByteBuffer #1005

Description

@belugabehr

Hello!

I've been recently looking at some Java Flight Recordings and noticed a lot of JVM churn related to the Encoder.

/**
* Encode an event as bytes.
*
* @param event
*/
byte[] encode(E event);

I have a custom Encoder that looks something like this:

public byte[] encode(E event) {
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();

    write(event, baos)

    return baos.toByteArray();
}

And what I find is that we spend a lot of heap churn on the final call of .toByteArray() because it must make a copy of the data for every call to encode. Ideally, I could instead do something like:

public ByteBuffer encode(E event) {
    // A simple subclass to get access to the protected 'buf' and 'count' fields
    class ExposedBAOS extends ByteArrayOutputStream {
        ByteBuffer getBuffer() {
            return ByteBuffer.wrap(this.buf, 0, this.count);
        }
    }

    final ExposedBAOS baos = new ExposedBAOS();
    write(event, baos);
    return baos.getBuffer();
}

... and avoid that altogether. I think this could be achieved with:

/**
     * Encodes an event into a ByteBuffer. 
     * Default implementation wraps the result of encode(E event).
     */
    default ByteBuffer encodeBuffer(E event) {
        byte[] encoded = encode(event);
        return (encoded != null) ? ByteBuffer.wrap(encoded) : null;
    }

    /**
     * Encode an event as bytes.
     */
    byte[] encode(E event);

Then update the callers to use the encodeBuffer method instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions