Documentation
¶
Overview ¶
Package swar provides SWAR (SIMD within a register) primitives for processing eight ASCII bytes per uint64 word. The building blocks here are the ones the rest of gofiber/utils composes into case conversion, multi-needle scanning, and validation loops, and they are exported so that downstream packages (fiber itself, middleware) can fuse their own scans — e.g. finding a delimiter while simultaneously classifying the bytes before it — without re-deriving the bit tricks.
Every operation yields per-lane results (exactly for the Match* masks, approximately for ZeroLanes, whose contract allows false positives above the first hit), so results are identical on little- and big-endian platforms. Load8 and Store8 always use little-endian lane order: lane 0 (the least significant byte) is the lowest byte index, which is what FirstLane and LastLane assume. The empty-mask sentinels differ on purpose: FirstLane(0) == 8 lets forward scans step past the current word arithmetically, while LastLane(0) == -1 is the conventional not-found result for reverse scans.
No unsafe is used anywhere in this package.
Index ¶
- Constants
- func Broadcast(c byte) uint64
- func FirstLane(mask uint64) int
- func LastLane(mask uint64) int
- func Load8[S ~string | ~[]byte](s S, i int) uint64
- func MatchByteMask(w uint64, c byte) uint64
- func MatchRangeMask(w uint64, lo, hi byte) uint64
- func Store8(b []byte, i int, w uint64)
- func ToLowerWord(w uint64) uint64
- func ToUpperWord(w uint64) uint64
- func ZeroLanes(x uint64) uint64
Examples ¶
Constants ¶
const ( // WordLen is the SWAR word width in bytes. Word loops should iterate // while i+WordLen <= len(s) and route shorter inputs to scalar code. WordLen = 8 // Ones has 0x01 in every byte lane. Ones = 0x0101010101010101 // HighBits has 0x80 in every byte lane; w&HighBits != 0 iff some byte // has its high bit set, and Match* masks equal HighBits iff every lane // matched. HighBits = 0x8080808080808080 // LowSeven has 0x7F in every byte lane. LowSeven = 0x7f7f7f7f7f7f7f7f )
Variables ¶
This section is empty.
Functions ¶
func Broadcast ¶
Broadcast returns a word with c in every byte lane, the needle form that ZeroLanes scans consume. Hoist the result out of word loops; it compiles to a single multiply.
func FirstLane ¶
FirstLane returns the index (0..7) of the lowest-addressed set lane in mask — the smallest byte index, given Load8's lane order — or 8 if mask is zero. mask must contain only 0x80 lane markers, as produced by the Match* functions.
func LastLane ¶
LastLane returns the index (0..7) of the highest-addressed set lane in mask, or -1 if mask is zero. mask must contain only 0x80 lane markers.
func Load8 ¶
Load8 assembles s[i:i+8] into a little-endian uint64: s[i] becomes the least significant byte (lane 0). The caller must guarantee i+8 <= len(s); the reslice below turns a violation into a bounds panic. The 8-byte reslice pins the length so the constant-index reads are bounds-check free, and the compiler fuses them into a single 8-byte load on little-endian targets (verified for both the string and []byte instantiations).
Example ¶
ExampleLoad8 shows the little-endian lane order: the byte at the lowest index becomes lane 0, the least significant byte of the word.
package main
import (
"fmt"
"github.com/gofiber/utils/v2/swar"
)
func main() {
w := swar.Load8([]byte("ABCDEFGH"), 0)
fmt.Printf("lane0=%c lane7=%c\n", byte(w), byte(w>>56)) //nolint:errcheck // example output
}
Output: lane0=A lane7=H
func MatchByteMask ¶
MatchByteMask returns a word with 0x80 set in exactly the lanes of w whose byte equals c, and zero in all other lanes. The result is per-lane exact (no false positives in lanes above a match), so it is safe to feed to LastLane or to arbitrary lane masking, not just first-match scans; for pure first-match scanning ZeroLanes is cheaper.
func MatchRangeMask ¶
MatchRangeMask returns a word with 0x80 set in exactly the lanes of w whose byte is within [lo, hi]. It requires lo <= hi <= 0x7F; lanes with the high bit set (bytes >= 0x80) never match.
Example ¶
ExampleMatchRangeMask classifies one word of input: which lanes hold an ASCII digit, and where the first and last digit sit.
package main
import (
"fmt"
"github.com/gofiber/utils/v2/swar"
)
func main() {
w := swar.Load8("Fiber123", 0)
digits := swar.MatchRangeMask(w, '0', '9')
fmt.Println(swar.FirstLane(digits), swar.LastLane(digits)) //nolint:errcheck // example output
}
Output: 5 7
func Store8 ¶
Store8 writes w into b[i:i+8] in Load8's lane order: lane 0 (the least significant byte) lands at the lowest byte index, so a Load8/Store8 round trip is the identity. The caller must guarantee i+8 <= len(b); the reslice below turns a violation into a bounds panic. Like Load8, the constant-index writes are bounds-check free and fuse into a single 8-byte store on little-endian targets.
func ToLowerWord ¶
ToLowerWord lower-cases every 'A'..'Z' lane in w. All other bytes, including those >= 0x80, pass through unchanged — bit-identical to the ASCII case-conversion tables used elsewhere in this module.
func ToUpperWord ¶
ToUpperWord upper-cases every 'a'..'z' lane in w. All other bytes, including those >= 0x80, pass through unchanged.
func ZeroLanes ¶
ZeroLanes returns a mask whose lowest set lane is the lowest zero-byte lane of x; higher lanes may carry false positives (borrows propagate strictly upward from true zero lanes), and the mask is zero iff x has no zero byte. It is two ops cheaper than MatchByteMask, which makes it the right primitive for first-match scans, typically as ZeroLanes(w ^ Broadcast(c)) with the broadcast hoisted out of the word loop. Use MatchByteMask when every lane must be exact.
Example ¶
ExampleZeroLanes shows the canonical first-match scan: broadcast the needle once, scan full words, and finish 8+ byte inputs with one overlapping word at len(s)-8. The overlap is safe because lanes before the loop's exit index are known non-matching, so the first set lane always falls into the new bytes.
package main
import (
"fmt"
"github.com/gofiber/utils/v2/swar"
)
func main() {
indexByte := func(s string, c byte) int {
n := len(s)
if n < swar.WordLen {
for i := range n {
if s[i] == c {
return i
}
}
return -1
}
needle := swar.Broadcast(c)
i := 0
for ; i+swar.WordLen <= n; i += swar.WordLen {
if m := swar.ZeroLanes(swar.Load8(s, i) ^ needle); m != 0 {
return i + swar.FirstLane(m)
}
}
if i == n {
return -1
}
if m := swar.ZeroLanes(swar.Load8(s, n-swar.WordLen) ^ needle); m != 0 {
return n - swar.WordLen + swar.FirstLane(m)
}
return -1
}
fmt.Println(indexByte("cache-control: no-store", ':')) //nolint:errcheck // example output
fmt.Println(indexByte("etag", ':')) //nolint:errcheck // example output
}
Output: 13 -1
Example (BlockScan) ¶
ExampleZeroLanes_blockScan shows the multi-word variant of the first-match scan: compute each word's mask independently, test their OR once per block, and resolve the lower word first. Combining is safe for first-match scans because a ZeroLanes mask is zero iff its word has no match and its lowest set lane is exact — so when only the second word matched, its first set lane is still the true first match. Exact masks (MatchByteMask, MatchRangeMask) may be combined the same way, block width is free to grow (four words per branch is common for long inputs), and the resolve ladder extends one `if` per extra word.
package main
import (
"fmt"
"github.com/gofiber/utils/v2/swar"
)
func main() {
indexByte := func(s string, c byte) int {
needle := swar.Broadcast(c)
i := 0
for ; i+16 <= len(s); i += 16 {
m0 := swar.ZeroLanes(swar.Load8(s, i) ^ needle)
m1 := swar.ZeroLanes(swar.Load8(s, i+8) ^ needle)
if m0|m1 != 0 {
if m0 != 0 {
return i + swar.FirstLane(m0)
}
return i + 8 + swar.FirstLane(m1)
}
}
for ; i+8 <= len(s); i += 8 {
if m := swar.ZeroLanes(swar.Load8(s, i) ^ needle); m != 0 {
return i + swar.FirstLane(m)
}
}
// A scalar tail keeps the example focused on block combining; see
// ExampleZeroLanes for the overlapping-word finish.
for ; i < len(s); i++ {
if s[i] == c {
return i
}
}
return -1
}
fmt.Println(indexByte("cache-control: public, max-age=604800, immutable", '=')) //nolint:errcheck // example output
fmt.Println(indexByte("cache-control: public", '=')) //nolint:errcheck // example output
}
Output: 30 -1
Types ¶
This section is empty.