# Types

> StringZilla for Java

`import com.stringzilla.*;`

## StringZilla

Core [StringZilla](#StringZilla) operations: search, compare, hash.

```java
class StringZilla
```

Pure FFM, JDK 22+.

## indexOf

First byte offset of needle in the off-heap haystack, or -1.

```java
long indexOf(MemorySegment haystack, MemorySegment needle);
```

```java
long indexOf(byte[] haystack, byte[] needle);
```

First byte offset of needle in haystack, or -1.

```java
long indexOf(byte[] haystack, int off, int len, byte[] needle);
```

Like `indexOf(byte[], byte[])`, but searches len bytes of haystack from off, and the returned offset is relative to off.

Like `String#indexOf(String)`, but SIMD-accelerated over UTF-8 bytes. Keywords: find, search, substring.

## lastIndexOf

Last byte offset of needle in the off-heap haystack, or -1.

```java
long lastIndexOf(MemorySegment haystack, MemorySegment needle);
```

```java
long lastIndexOf(byte[] haystack, byte[] needle);
```

Last byte offset of needle in haystack, or -1.

The byte[] form of `lastIndexOf(MemorySegment, MemorySegment)`.

## indexOfAny

First offset of any byte in set, or -1.

```java
long indexOfAny(byte[] haystack, Byteset set);
```

## lastIndexOfAny

Last offset of any byte in set, or -1.

```java
long lastIndexOfAny(byte[] haystack, Byteset set);
```

The reverse of `[indexOfAny](#indexOfAny)`.

## equal

Byte-wise equality.

```java
boolean equal(byte[] a, byte[] b);
```

Like `java.util.Arrays#equals(byte[], byte[])`, SIMD-accelerated.

## compare

Lexicographic byte comparison: -1, 0, or 1.

```java
int compare(byte[] a, byte[] b);
```

Like `java.util.Arrays#compare(byte[], byte[])`.

## hash

Fast 64-bit AES-based hash (SMHasher-quality), stable across runs and identical across all [StringZilla](#StringZilla) bindings — unlike `String#hashCode()`.

```java
long hash(byte[] data);
```

```java
long hash(byte[] data, long seed);
```

Like `hash(byte[])`, under the given seed.

```java
long hash(MemorySegment data, long seed);
```

Like `hash(byte[], long)`, over a MemorySegment.

For cryptographic hashing use `[Sha256](#Sha256)`.

## byteSum

Sums the bytes of data, computed by the native sz_bytesum_best.

```java
long byteSum(byte[] data);
```

## countRunes

Counts Unicode scalar values (codepoints).

```java
long countRunes(byte[] text);
```

```java
long countRunes(MemorySegment text);
```

Like `countRunes(byte[])`, over a MemorySegment.

Like String.codePointCount / `Character#codePointCount`, SIMD-accelerated over UTF-8 bytes. For example, "你好世界" counts 4 and "Hello🌍" counts 6 — the astral emoji is a single scalar.

## seekRune

Byte offset of the index-th codepoint (0-based), or -1 if fewer exist.

```java
long seekRune(byte[] text, long index);
```

## decode

Decodes codepoints into destination (one Int32 scalar each; ill-formed or truncated → U+FFFD) and returns the count written, stopping early only when destination fills.

```java
int decode(byte[] text, int[] destination);
```

```java
int decode(MemorySegment text, int[] destination);
```

Like `decode(byte[], int[])`, over a MemorySegment.

Like String.codePoints(), SIMD-accelerated.

## decodeAll

Allocating convenience: returns all codepoints as a fresh Int32 array.

```java
int[] decodeAll(byte[] text);
```

```java
int[] decodeAll(MemorySegment text);
```

Like `decodeAll(byte[])`, over a MemorySegment.

## segment

Writes the byte lengths of the next segments of text, from textOffset for textLength bytes, into the caller's lengths and returns the count written.

```java
int segment(
    byte[] text,
    int textOffset,
    int textLength,
    SegmentKind kind,
    long[] lengths);
```

```java
int segment(
    MemorySegment text,
    long textOffset,
    long textLength,
    SegmentKind kind,
    long[] lengths);
```

Like `segment(byte[], int, int, SegmentKind, long[])`, over a MemorySegment with long bounds.

Allocation-free. [Segments](#Segments) tile the text, each starting where the previous one ended, so resume at the sum of the lengths; only an empty text yields 0. Like `java.text.BreakIterator` / ICU4J, but deterministic, SIMD-accelerated, over UTF-8 bytes (no locale, no transcode). By GRAPHEMES, the flag 🇺🇸 is one cluster spanning two codepoints; by WORDS, "Hello, 世界" splits the Latin run from the CJK run.

## caseFold

Folds into the caller's destination (must hold ≥ text.length*3 bytes) and returns the bytes written.

```java
int caseFold(byte[] text, byte[] destination);
```

```java
byte[] caseFold(byte[] text);
```

Full Unicode case folding (UAX #21, one-to-many, e.g.

Allocation-free.

## uncasedIndexOf

Case-insensitive (full-fold) search.

```java
Match uncasedIndexOf(byte[] haystack, byte[] needle);
```

Fills a gap: no JDK caseless UTF-8 substring search. For repeated searches with the same needle, prefer `[UncasedNeedle](#UncasedNeedle)`.

## uncasedCompare

Case-insensitive (full-fold) lexicographic comparison: -1, 0, or 1.

```java
int uncasedCompare(byte[] a, byte[] b);
```

Fills a gap: no JDK Unicode case-folded ordinal comparison.

## hashMultiseed

Hashes data under each seed, writing results into hashes (must hold ≥ seeds.length).

```java
void hashMultiseed(byte[] data, long[] seeds, long[] hashes);
```

```java
long[] hashMultiseed(byte[] data, long[] seeds);
```

Allocating convenience: returns one hash per seed.

## fillRandom

Fills buffer with deterministic pseudo-random bytes derived from nonce.

```java
void fillRandom(byte[] buffer, long nonce);
```

## lookup

Byte-wise table transform: destination[i] = lut[source[i]].

```java
void lookup(byte[] destination, byte[] source, byte[] lut);
```

lut must be 256 bytes.

## normalize

Normalizes into the caller's destination (must hold ≥ text.length*18 bytes) and returns the bytes written.

```java
int normalize(byte[] text, NormalForm form, byte[] destination);
```

```java
byte[] normalize(byte[] text, NormalForm form);
```

Normalizes text to the given form.

Allocation-free.

## isNormalized

True if text is already in the given form.

```java
boolean isNormalized(byte[] text, NormalForm form);
```

Like `java.text.Normalizer#isNormalized`.

## argSort

Returns the permutation that sorts items lexicographically by bytes (stable).

```java
int argSort(
    java.util.List<byte[]> items,
    long[] order,
    boolean reverse,
    long top,
    boolean uncased);
```

```java
long[] argSort(
    java.util.List<byte[]> items,
    boolean reverse,
    long top,
    boolean uncased);
```

Allocating convenience: returns a fresh permutation array.

```java
long[] argSort(java.util.List<byte[]> items);
```

Returns the ascending, case-sensitive permutation of all items, as `[argSort](#argSort)` with no limit.

```java
int argSort(
    byte[] text,
    long[] starts,
    long[] lengths,
    long[] order,
    boolean reverse,
    long top,
    boolean uncased);
```

Sorts the segments of a single buffer — given per-segment starts and lengths (as produced by the split iterators) — writing their sorting permutation into order (must hold ≥ starts.length entries) and returning the count.

top > 0 partial-sorts the smallest N. Like Collections.sort with an ordinal comparator, but returns indices over UTF-8 bytes. Writes the sorting permutation of items into order (must hold ≥ items.size() entries) and returns the count of sorted indices (top if > 0, else items.size()). Like Collections.sort with an ordinal comparator, but returns indices over UTF-8 bytes.

## intersect

Inner-join two de-duplicated sequences.

```java
int intersect(
    java.util.List<byte[]> a,
    java.util.List<byte[]> b,
    long[] firstPositions,
    long[] secondPositions,
    long seed);
```

```java
int intersect(
    java.util.List<byte[]> a,
    java.util.List<byte[]> b,
    long[] firstPositions,
    long[] secondPositions);
```

Like `[intersect](#intersect)`, seed 0.

Returns {firstPositions, secondPositions} — the matching index pairs into a and b. Inner-joins two de-duplicated sequences, writing matching index pairs into firstPositions and secondPositions (each must hold ≥ min(a.size(), b.size()) entries) and returns the match count. Allocation-free for the result.

## runes

Decodes the Unicode scalar values (codepoints) as an IntStream.

```java
IntStream runes(byte[] text);
```

```java
IntStream runes(MemorySegment text);
```

Like `runes(byte[])`, over a MemorySegment.

Like String.codePoints(). Eager (decodes the whole input up front); for incremental decoding use `decode(byte[], int[])`.

## words

Lazily yields the word segments (UAX #29) as zero-copy `MemorySegment` views, or a zero-allocation `[Segmenter](#Segmenter)` cursor via `Segments#cursor()`.

```java
Segments words(byte[] text);
```

```java
Segments words(MemorySegment text);
```

Like `words(byte[])`, over a MemorySegment.

Accepts an on-heap byte[] or any `MemorySegment` (e.g. a Spark UTF8String or an mmap'd file).

## graphemes

Lazily yields the grapheme cluster segments, like `words(byte[])`.

```java
Segments graphemes(byte[] text);
```

```java
Segments graphemes(MemorySegment text);
```

Like `graphemes(byte[])`, over a MemorySegment.

## sentences

Lazily yields the sentence segments, like `words(byte[])`.

```java
Segments sentences(byte[] text);
```

```java
Segments sentences(MemorySegment text);
```

Like `sentences(byte[])`, over a MemorySegment.

## lineBreaks

Lazily yields the segments between line-break opportunities, like `words(byte[])`.

```java
Segments lineBreaks(byte[] text);
```

```java
Segments lineBreaks(MemorySegment text);
```

Like `lineBreaks(byte[])`, over a MemorySegment.

## split

Lazily splits text on each occurrence of separator, yielding the segments between separators as zero-copy views.

```java
Splits split(byte[] text, byte[] separator);
```

```java
Splits split(MemorySegment text, MemorySegment separator);
```

Like `split(byte[], byte[])`, over MemorySegment inputs.

Empty segments are kept by default (like String.split with a negative limit); chain .skipEmpty(), .keepSeparator(), or .withMaxSplit(n). Off-heap `MemorySegment` inputs are scanned in place; on-heap inputs are copied off-heap once per cursor() (pointer-returning finds need a stable address).

## rsplit

As `[split](#split)` but scanning from the end; yields the last segment first.

```java
Splits rsplit(byte[] text, byte[] separator);
```

```java
Splits rsplit(MemorySegment text, MemorySegment separator);
```

Like `rsplit(byte[], byte[])`, over MemorySegment inputs.

## splitAny

Lazily splits on any byte in separators (like splitting on a character set).

```java
Splits splitAny(byte[] text, Byteset separators);
```

```java
Splits splitAny(MemorySegment text, Byteset separators);
```

Like `splitAny(byte[], Byteset)`, over a MemorySegment.

## rsplitAny

As `[splitAny](#splitAny)` but scanning from the end.

```java
Splits rsplitAny(byte[] text, Byteset separators);
```

```java
Splits rsplitAny(MemorySegment text, Byteset separators);
```

Like `rsplitAny(byte[], Byteset)`, over a MemorySegment.

## splitNewlines

Lazily splits on Unicode newline runs, yielding the lines between them.

```java
TokenSplits splitNewlines(byte[] text);
```

```java
TokenSplits splitNewlines(MemorySegment text);
```

Like `splitNewlines(byte[])`, over a MemorySegment.

Chain .withSeparators() for a lossless interleave or .skipEmpty() to drop blanks.

## splitWhitespaces

Lazily splits on Unicode whitespace, as `splitNewlines(byte[])` does on newlines.

```java
TokenSplits splitWhitespaces(byte[] text);
```

```java
TokenSplits splitWhitespaces(MemorySegment text);
```

Like `splitWhitespaces(byte[])`, over a MemorySegment.

## splitDelimiters

Lazily splits on Unicode delimiters, as `splitNewlines(byte[])` does on newlines.

```java
TokenSplits splitDelimiters(byte[] text);
```

```java
TokenSplits splitDelimiters(MemorySegment text);
```

Like `splitDelimiters(byte[])`, over a MemorySegment.

## matches

Lazily enumerates the byte offsets of every match of needle in haystack; chain .overlapping() for overlapping matches.

```java
Matches matches(byte[] haystack, byte[] needle);
```

```java
Matches matches(MemorySegment haystack, MemorySegment needle);
```

Like `matches(byte[], byte[])`, over MemorySegment inputs.

Counting the result is the occurrence count.

## uncasedMatches

Lazily enumerates case-insensitive (full-fold) matches; chain .overlapping().

```java
UncasedMatches uncasedMatches(byte[] haystack, byte[] needle);
```

```java
UncasedMatches uncasedMatches(
    MemorySegment haystack,
    MemorySegment needle);
```

Like `uncasedMatches(byte[], byte[])`, over MemorySegment inputs.

Each `[Match](#Match)` carries the offset and matched length (folding may make the latter differ). An empty needle matches at every codepoint boundary, the end included.

## partition

[Splits](#Splits) at the first occurrence of separator into (before, separator, after) views; if absent, returns (text, empty, empty).

```java
Partition partition(byte[] text, byte[] separator);
```

```java
Partition partition(MemorySegment text, MemorySegment separator);
```

Like `partition(byte[], byte[])`, over MemorySegment inputs.

## rpartition

As `[partition](#partition)` but at the last occurrence; if absent, returns (empty, empty, text).

```java
Partition rpartition(byte[] text, byte[] separator);
```

```java
Partition rpartition(MemorySegment text, MemorySegment separator);
```

Like `rpartition(byte[], byte[])`, over MemorySegment inputs.

## capabilitiesName

Names the bits of capabilities, comma-separated, like "serial,haswell,skylake".

```java
String capabilitiesName(long capabilities);
```

## version

The native library version, formatted as major.minor.patch.

```java
String version();
```

## Match

Result of a case-insensitive search: byte offset (-1 if not found) and the matched byte length (may differ from the needle due to folding).

```java
record Match(long offset, long matchedLength);
```

## Device

One device [StringZilla](#StringZilla) can run on: the host CPU, or a GPU by its runtime's own ordinal, the one cudaSetDevice or hipSetDevice takes, or the position in Metal's device list.

```java
record Device(DeviceKind kind, long ordinal);
```

Every call of this class dispatches over the CPU's `capabilitiesEnabled()`; GPUs only report their masks.

Prefer `capabilitiesEnabled()` unless you specifically mean one of the raw axes: `capabilitiesDetected()` describes the device and says nothing about whether a kernel was compiled into this binary, so selecting on it alone claims support for code that may not exist.

## Partition

A single split point: the spans before, of, and after a separator.

```java
record Partition(
    MemorySegment before,
    MemorySegment separator,
    MemorySegment after);
```

See `[partition](#partition)`.

## SegmentKind

A tiling segmentation: every byte lands in exactly one segment.

```java
enum SegmentKind
```

- `GRAPHEMES` ``: Grapheme clusters.
- `WORDS` ``: Word segments.
- `SENTENCES` ``: Sentence segments.
- `LINE_BREAKS` ``: [Segments](#Segments) between line-break opportunities.

## TokenKind

The separator tokens that `[TokenSplits](#TokenSplits)` splits on.

```java
enum TokenKind
```

- `NEWLINES` ``: Unicode newlines.
- `WHITESPACES` ``: Unicode whitespace.
- `DELIMITERS` ``: Unicode delimiters.

## NormalForm

Unicode normalization forms, NFKC_CASEFOLD being NFKC with full case folding and without default-ignorable codepoints, the Unicode toNFKC_Casefold that caseless keys match on.

```java
enum NormalForm
```

- `NFD` ``: Canonical decomposition.
- `NFC` ``: Canonical decomposition followed by canonical composition.
- `NFKD` ``: Compatibility decomposition.
- `NFKC` ``: Compatibility decomposition followed by canonical composition.
- `NFKC_CASEFOLD` ``: NFKC with full case folding, as described on `[NormalForm](#NormalForm)`.

## DeviceKind

Which runtime a device belongs to, as the sz_<kind>_* C functions name it.

```java
enum DeviceKind
```

- `CPU` ``: The host CPU.
- `CUDA` ``: NVIDIA GPUs, through CUDA.
- `ROCM` ``: AMD GPUs, through ROCm.
- `METAL` ``: Apple GPUs, through Metal.

## StatusException

A native call returned a non-success sz_status_t, kept in `status()`.

```java
class StatusException
```

## Byteset

A 256-bit set of byte values.

```java
class Byteset
```

## Hasher

Incremental (streaming) hash.

```java
class Hasher
```

Close to free the native state.

## UncasedNeedle

A case-folding search needle, prepared once and reusable from any thread.

```java
class UncasedNeedle
```

Close to free native memory.

## Sha256

Incremental SHA-256.

```java
class Sha256
```

Close to free the native state.

## SplitParts

Which spans a separator-token split yields: the gaps, the separator runs, or both (lossless).

```java
enum SplitParts
```

- `BETWEEN` ``: The gaps between separator runs.
- `SEPARATORS` ``: The separator runs only.
- `BOTH` ``: The gaps and the separator runs, interleaved.

## Segmenter

Zero-allocation forward cursor over tiling UTF-8 segments (words, graphemes, …).

```java
class Segmenter
```

Reuses one 64-entry batch buffer; call `next()` then read `startOffset()`/`length()`.

## Segments

Iterable / streamable view over tiling segments, yielding zero-copy `MemorySegment` slices.

```java
class Segments
```

Use `cursor()` for the zero-allocation path.

## Splitter

Zero-allocation cursor over substring / byte-set splits, with forward and reverse scanning and the keepSeparator / skipEmpty / maxSplit policies.

```java
class Splitter
```

## Splits

Iterable / streamable view over substring or byte-set splits.

```java
class Splits
```

Fluent policies return a new view; `cursor()` is the zero-allocation path.

## TokenSplitter

Zero-allocation cursor over separator-token splits (newlines, whitespace, delimiters), batched 64 separators per native call, applying the `[SplitParts](#SplitParts)` policy.

```java
class TokenSplitter
```

## TokenSplits

Iterable / streamable view over separator-token splits, yielding zero-copy slices.

```java
class TokenSplits
```

## Matcher

Zero-allocation cursor over substring matches, yielding each match's byte offset.

```java
class Matcher
```

## Matches

Streamable view over substring matches; `overlapping()` reports overlapping matches and `cursor()` is the zero-allocation path.

```java
class Matches
```

An empty needle matches at every offset, the end included.

## UncasedMatcher

Zero-allocation cursor over case-insensitive matches of a needle prepared once.

```java
class UncasedMatcher
```

## UncasedMatches

Streamable view over case-insensitive matches; `overlapping()` and `cursor()` mirror `[Matches](#Matches)`.

```java
class UncasedMatches
```

