public static <T> long hash(final T input, final Access<T> access, final int off, final int length, final long seed) {
    if (length <= 16) {
      // len_0to16_64b
      if (length > 8) {
        // len_9to16_64b
        final long bitflip1 = secretLong[24] ^ secretLong[32] + seed;
        final long bitflip2 = secretLong[40] ^ secretLong[48] - seed;
        final long input_lo = access.i64(input, off) ^ bitflip1;
        final long input_hi = access.i64(input, off + length - 8) ^ bitflip2;
        final long acc = length + Long.reverseBytes(input_lo) + input_hi + unsignedLongMulXorFold(input_lo, input_hi);
        return avalanche(acc);
      }
      if (length >= 4) {
        // len_4to8_64b
        long s = seed ^ Long.reverseBytes(seed & 0xFFFFFFFFL);
        final long input1 = access.i32(input, off); // high int will be shifted
        final long input2 = access.u32(input, off + length - 4);
        final long bitflip = (secretLong[8] ^ secretLong[16]) - s;
        final long keyed = (input2 + (input1 << 32)) ^ bitflip;
        return rrmxmx(keyed, length);
      }
      if (length != 0) {
        // len_1to3_64b
        final int c1 = access.i8(input, off) & 0xff;
        final int c2 = access.i8(input, off + (length >> 1)); // high 3 bytes will be shifted
        final int c3 = access.i8(input, off + length - 1) & 0xff;
        final long combined = unsignedInt((c1 << 16) | (c2 << 24) | c3 | (length << 8));
        final long bitflip = unsignedInt(secretInt[0] ^ secretInt[4]) + seed;
        return XXH64_avalanche(combined ^ bitflip);
      }
      return XXH64_avalanche(seed ^ secretLong[56] ^ secretLong[64]);
    }
    if (length <= 128) {
      // len_17to128_64b
      long acc = length * XXH_PRIME64_1;

      if (length > 32) {
        if (length > 64) {
          if (length > 96) {
            acc += mix16B(seed, input, access, off + 48, 96);
            acc += mix16B(seed, input, access, off + length - 64, 112);
          }
          acc += mix16B(seed, input, access, off + 32, 64);
          acc += mix16B(seed, input, access, off + length - 48, 80);
        }
        acc += mix16B(seed, input, access, off + 16, 32);
        acc += mix16B(seed, input, access, off + length - 32, 48);
      }
      acc += mix16B(seed, input, access, off, 0);
      acc += mix16B(seed, input, access, off + length - 16, 16);

      return avalanche(acc);
    }
    return hashLarge(input, access, off, length, seed);
  }
public static <T> long hash(final T input, final Access<T> access, final int off, final int length, final long seed)