Files
Flash5/flash/src/main/java/dev/relism/flash/bytes/ArrayBackedByteView.java
T

37 lines
1.9 KiB
Java

package dev.relism.flash.bytes;
import dev.relism.fpr.core.ByteView;
/**
* Capability interface for a {@link ByteView} that is a contiguous slice of a single backing
* {@code byte[]} — as opposed to a {@link SegmentedByteView}, which spans several arrays and
* cannot expose a single {@code (array, offset)} pair.
*
* <p>Every array-backed view in this codebase implements this: {@code RequestByteView},
* {@code SocketByteView}, {@code StringByteView} (all in
* {@code dev.relism.flash.routing.routers.fastpathrouter.FastPathViews}), and {@link PooledSlice}.
* {@code MethodPathByteView} deliberately does not — it is a composite of a {@code byte[]}
* (method) and another {@link ByteView} (path), so it has no single backing array.
*
* <h3>What this enables</h3>
* Anywhere code holds a plain {@link ByteView} and wants the fast path when the concrete
* instance happens to be array-backed, an {@code instanceof ArrayBackedByteView} check unlocks:
* <ul>
* <li>Single-allocation {@code String} construction —
* {@code new String(view.array(), view.offset(), view.length(), UTF_8)} instead of a
* byte-at-a-time copy into a scratch {@code byte[]} followed by a second allocation for
* <li>A single {@code System.arraycopy} instead of a manual loop wherever a view's bytes need
* to be copied.</li>
* </ul>
* Code that only has a bare {@link ByteView} (e.g. because it received one across the
* {@link SegmentedByteView} boundary, from a future HPACK CONTINUATION-spanning block) keeps the
* byte-at-a-time fallback — this interface is an opportunistic fast path, never a requirement.
*/
public interface ArrayBackedByteView extends ByteView {
/** The backing array. Bytes {@code [offset(), offset() + length())} belong to this view. */
byte[] array();
/** Offset of this view's first byte within {@link #array()}. */
int offset();
}