Class SWARUtil
Copied from the Netty Project. https://github.com/netty/netty/blob/d28a0fc6598b50fbe8f296831777cf4b653a475f/common/src/main/java/io/netty/util/internal/SWARUtil.java
Multi-byte reads use MethodHandles.byteArrayViewVarHandle(java.lang.Class<?>, java.nio.ByteOrder), which allows
reading several bytes from a byte array as a single typed value (e.g. short, int,
or long) in one operation rather than reading and shifting each byte individually.
The JDK itself uses the same technique. Since Java 17, jdk.internal.util.ByteArray (big
endian) and jdk.internal.util.ByteArrayLittleEndian (little endian) use
MethodHandles.byteArrayViewVarHandle for every primitive type, and those helpers back the
public APIs of java.io.DataInputStream (readShort, readInt,
readLong, etc.) and java.util.UUID construction from bytes.
Why this is faster than byte-by-byte shifts
- Single native load instruction – on x86/x64 and AArch64 the HotSpot JIT intrinsifies
the VarHandle access into a single
MOVZX,MOV, orLDRinstruction that reads the full value directly from memory, whereas manual byte-shift code requires multiple load-and-shift-and-or sequences that are harder for the JIT to collapse. - Consolidated bounds check – a single range check covers the entire multi-byte read;
individual
array(i)accesses each carry their own implicit bounds check. - No alignment requirement – unlike
sun.misc.Unsafethe VarHandle variant works correctly on unaligned offsets, so callers do not need to pad or copy data to satisfy alignment constraints. - SWAR arithmetic – reading a full
longwith a single VarHandle call means eight bytes arrive in one register, enabling SWAR patterns that test all eight bytes in parallel (seeapplyPattern(long,long)).
A runtime try/catch guards each VarHandle creation; if the JVM does not support the API
(e.g. older Android runtimes) the code falls back to explicit byte-by-byte shift implementations
(getLongBEWithoutMethodHandle, etc.) so behaviour is always correct.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic longapplyPattern(long word, long pattern) Applies a compiled pattern to given word.static longcompilePattern(byte byteToFind) Compiles given byte into a long pattern suitable for SWAR operations.static intgetIndex(long word) Returns the index of the first occurrence of byte specified in the pattern.static intReturns the int value at the specified index in the given byte array.static intgetLastIndex(long word) Returns the index of the last occurrence of a byte specified in the pattern within a word.static longReturns the long value at the specified index in the given byte array.static shortReturns the short value at the specified index in the given byte array.static voidWrites an int value at the specified index in the given byte array.static voidWrites a long value at the specified index in the given byte array.static voidWrites the low 16 bits ofvalueat the specified index in the given byte array.
-
Constructor Details
-
SWARUtil
public SWARUtil()
-
-
Method Details
-
compilePattern
public static long compilePattern(byte byteToFind) Compiles given byte into a long pattern suitable for SWAR operations. -
applyPattern
public static long applyPattern(long word, long pattern) Applies a compiled pattern to given word. Returns a word where each byte that matches the pattern has the highest bit set.- Parameters:
word- the word to apply the pattern topattern- the pattern to apply- Returns:
- a word where each byte that matches the pattern has the highest bit set
-
getIndex
public static int getIndex(long word) Returns the index of the first occurrence of byte specified in the pattern. If no pattern is found, returns 8. Currently only supports big endian.- Parameters:
word- the return value ofapplyPattern(long, long)- Returns:
- the index of the first occurrence of the specified pattern in the specified word. If no pattern is found, returns 8.
-
getLastIndex
public static int getLastIndex(long word) Returns the index of the last occurrence of a byte specified in the pattern within a word. If no pattern is found, the result is -1. Currently only supports big endian.- Parameters:
word- the return value ofapplyPattern(long,long)- Returns:
- the index of the last occurrence of the specified pattern in the specified word.
-
getLong
Returns the long value at the specified index in the given byte array. Uses big-endian byte order. Uses a VarHandle byte array view if supported. Does not range check - assumes caller has checked bounds.- Parameters:
array- the byte array to read fromindex- the index to read frombyteOrder- the byte order to use (big-endian or little-endian)- Returns:
- the long value at the specified index
-
getInt
Returns the int value at the specified index in the given byte array. Uses big-endian byte order. Uses a VarHandle byte array view if supported. Does not range check - assumes caller has checked bounds.- Parameters:
array- the byte array to read fromindex- the index to read frombyteOrder- the byte order to use (big-endian or little-endian)- Returns:
- the int value at the specified index
-
getShort
Returns the short value at the specified index in the given byte array. Uses big-endian byte order. Uses a VarHandle byte array view if supported. Does not range check - assumes caller has checked bounds.- Parameters:
array- the byte array to read fromindex- the index to read frombyteOrder- the byte order to use (big-endian or little-endian)- Returns:
- the short value at the specified index
-
putInt
Writes an int value at the specified index in the given byte array. Uses a VarHandle byte array view if supported, otherwise falls back to byte-by-byte writes. Does not range check - assumes caller has checked bounds.- Parameters:
array- the byte array to write toindex- the index to write atvalue- the int value to writebyteOrder- the byte order to use (big-endian or little-endian)
-
putShort
Writes the low 16 bits ofvalueat the specified index in the given byte array. Uses a VarHandle byte array view if supported, otherwise falls back to byte-by-byte writes. Does not range check - assumes caller has checked bounds.- Parameters:
array- the byte array to write toindex- the index to write atvalue- the value whose low 16 bits are writtenbyteOrder- the byte order to use (big-endian or little-endian)
-
putLong
Writes a long value at the specified index in the given byte array. Uses a VarHandle byte array view if supported, otherwise falls back to byte-by-byte writes. Does not range check - assumes caller has checked bounds.- Parameters:
array- the byte array to write toindex- the index to write atvalue- the long value to writebyteOrder- the byte order to use (big-endian or little-endian)
-