Class ByteMatchers

java.lang.Object
org.elasticsearch.xpack.esql.core.util.ByteMatchers

public final class ByteMatchers extends Object
Byte-level matching primitives shared by datasource pushdown evaluators.

All operations are byte-level — they treat their inputs as opaque byte[] and make no assumption about character encoding or case. Callers that work with valid UTF-8 KEYWORD values (the Elasticsearch contract) get codepoint-correct semantics for free thanks to UTF-8's self-synchronizing property: a valid UTF-8 substring matches at byte boundaries iff it matches at codepoint boundaries. For inputs that are not valid UTF-8, the helpers degrade to plain byte comparison — caller's responsibility if that diverges from the desired semantics.

Each primitive routes the heavy lifting through the fastest implementation available on the platform:

The methods are deliberately small and inlinable so the JIT can fuse them into per-row predicate loops without virtual-call overhead. Datasource evaluators (today: Parquet late-materialization; future: any in-Java filter on byte-shaped columns) should call these helpers rather than open-coding the byte loops.

  • Method Summary

    Modifier and Type
    Method
    Description
    static boolean
    affixContains(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef prefix, org.apache.lucene.util.BytesRef literal, org.apache.lucene.util.BytesRef suffix)
    Composite predicate: returns true iff value starts with prefix, ends with suffix, and contains literal as a contiguous subsequence anywhere between the matched prefix and suffix.
    static boolean
    containsLiteral(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef literal)
    Returns true iff value contains literal as a contiguous subsequence.
    static boolean
    endsWith(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef suffix)
    Returns true iff value ends with suffix.
    static boolean
    equals(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef target)
    Returns true iff the two byte sequences have identical length and content.
    static boolean
    startsWith(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef prefix)
    Returns true iff value begins with prefix.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • equals

      public static boolean equals(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef target)
      Returns true iff the two byte sequences have identical length and content. Equivalent to BytesRef.bytesEquals(BytesRef) but routed through Arrays.equals(byte[], int, int, byte[], int, int) so it picks up the JDK's vectorized intrinsic on hot paths.
    • startsWith

      public static boolean startsWith(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef prefix)
      Returns true iff value begins with prefix. An empty prefix matches every value (including an empty one). Returns false when prefix is longer than value.
    • endsWith

      public static boolean endsWith(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef suffix)
      Returns true iff value ends with suffix. An empty suffix matches every value (including an empty one). Returns false when suffix is longer than value.
    • containsLiteral

      public static boolean containsLiteral(org.apache.lucene.util.BytesRef value, org.apache.lucene.util.BytesRef literal)
      Returns true iff value contains literal as a contiguous subsequence. An empty literal matches every value (including an empty one). Routes through the SIMD substring search exposed by BinaryDocValuesContainsTermQuery.contains(byte[], int, int, BytesRef).

      The Lucene query class is used purely as a static-method shim around ESVectorUtil#contains: simdvec's module exports the SIMD utility only to org.elasticsearch.server, so plugins (unnamed modules) cannot import it directly. Calling it through this server-side neighbor keeps the SIMD intent without forcing every consumer plugin to add a simdvec dependency it cannot legally use at runtime. If the shim ever moves to a more semantically-named :server home, only this method needs to change.

    • affixContains

      public static boolean affixContains(org.apache.lucene.util.BytesRef value, @Nullable org.apache.lucene.util.BytesRef prefix, @Nullable org.apache.lucene.util.BytesRef literal, @Nullable org.apache.lucene.util.BytesRef suffix)
      Composite predicate: returns true iff value starts with prefix, ends with suffix, and contains literal as a contiguous subsequence anywhere between the matched prefix and suffix. Any of the three components may be null or empty, in which case the corresponding check is skipped.

      This implements the SQL LIKE 'prefix%literal%suffix' family in a single pass:

      • prefix*(prefix, null, null)
      • *suffix(null, null, suffix)
      • *literal*(null, literal, null)
      • prefix*suffix(prefix, null, suffix)
      • prefix*literal*(prefix, literal, null)
      • *literal*suffix(null, literal, suffix)
      • prefix*literal*suffix(prefix, literal, suffix)

      The order of checks is prefix → suffix → literal: the affix checks are short JDK- intrinsified equality comparisons (typically ≤ 32 bytes) and reject the bulk of non-matching values cheaply, leaving the more expensive SIMD substring scan for survivors. For correctness, the literal scan is restricted to the bytes strictly between the prefix and suffix regions: this prevents the literal from straddling and double-counting either affix region (e.g. value="aXa", prefix="a", literal="aXa", suffix="a" must match iff aXa appears in the empty middle slice — which it does not — not iff it appears anywhere in the full value).

      A single combined-length guard rejects any value that cannot host all three components end-to-end without overlap: when prefix.length + literal.length + suffix.length > value.length the predicate returns false immediately. This subsumes both the "affixes don't fit" case (literal length zero) and the "literal can't fit between the affixes" case, and it matches the non-overlapping-concatenation semantics that ByteRunAutomaton uses on the same patterns — the parity callers depend on.

      When all three components are absent (every parameter null or empty) this returns true unconditionally — the vacuum predicate. Callers typically partition that case upstream as a matchesAll fast path; reaching this method with all-null arguments is harmless but wasteful.