private static <T> long hashLarge(T input, Access<T> access, int off, int length, long seed) {
    if (length <= 240) {
      // len_129to240_64b
      long acc = length * XXH_PRIME64_1;
      final int nbRounds = length / 16;
      int i = 0;
      for (; i < 8; ++i) {
        acc += mix16B(seed, input, access, off + 16 * i, 16 * i);
      }
      acc = avalanche(acc);

      for (; i < nbRounds; ++i) {
        acc += mix16B(seed, input, access, off + 16 * i, 16 * (i - 8) + 3);
      }

      /* last bytes */
      acc += mix16B(seed, input, access, off + length - 16, 136 - 17);
      return avalanche(acc);
    }

    // hashLong_64b_internal
    long acc_0 = XXH_PRIME32_3;
    long acc_1 = XXH_PRIME64_1;
    long acc_2 = XXH_PRIME64_2;
    long acc_3 = XXH_PRIME64_3;
    long acc_4 = XXH_PRIME64_4;
    long acc_5 = XXH_PRIME32_2;
    long acc_6 = XXH_PRIME64_5;
    long acc_7 = XXH_PRIME32_1;

    // hashLong_internal_loop
    final int nb_blocks = (length - 1) / block_len;
    for (int n = 0; n < nb_blocks; n++) {
      // accumulate
      final int offBlock = off + n * block_len;
      for (int s = 0; s < nbStripesPerBlock; s++) {
        // accumulate_512
        final int offStripe = offBlock + s * 64;
        final int offSec = s * 8;
        {
          final long data_val_0 = access.i64(input, offStripe);
          final long data_val_1 = access.i64(input, offStripe + 8);
          final long data_key_0 = data_val_0 ^ secretLong[offSec];
          final long data_key_1 = data_val_1 ^ secretLong[offSec + 8];
          /* swap adjacent lanes */
          acc_0 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
          acc_1 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
        }
        {
          final long data_val_0 = access.i64(input, offStripe + 8 * 2);
          final long data_val_1 = access.i64(input, offStripe + 8 * 3);
          final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 2];
          final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 3];
          /* swap adjacent lanes */
          acc_2 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
          acc_3 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
        }
        {
          final long data_val_0 = access.i64(input, offStripe + 8 * 4);
          final long data_val_1 = access.i64(input, offStripe + 8 * 5);
          final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 4];
          final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 5];
          /* swap adjacent lanes */
          acc_4 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
          acc_5 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
        }
        {
          final long data_val_0 = access.i64(input, offStripe + 8 * 6);
          final long data_val_1 = access.i64(input, offStripe + 8 * 7);
          final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 6];
          final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 7];
          /* swap adjacent lanes */
          acc_6 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
          acc_7 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
        }
      }

      // scrambleAcc_scalar
      final int offSec = 192 - 64;
      acc_0 = (acc_0 ^ (acc_0 >>> 47) ^ secretLong[offSec]) * XXH_PRIME32_1;
      acc_1 = (acc_1 ^ (acc_1 >>> 47) ^ secretLong[offSec + 8]) * XXH_PRIME32_1;
      acc_2 = (acc_2 ^ (acc_2 >>> 47) ^ secretLong[offSec + 8 * 2]) * XXH_PRIME32_1;
      acc_3 = (acc_3 ^ (acc_3 >>> 47) ^ secretLong[offSec + 8 * 3]) * XXH_PRIME32_1;
      acc_4 = (acc_4 ^ (acc_4 >>> 47) ^ secretLong[offSec + 8 * 4]) * XXH_PRIME32_1;
      acc_5 = (acc_5 ^ (acc_5 >>> 47) ^ secretLong[offSec + 8 * 5]) * XXH_PRIME32_1;
      acc_6 = (acc_6 ^ (acc_6 >>> 47) ^ secretLong[offSec + 8 * 6]) * XXH_PRIME32_1;
      acc_7 = (acc_7 ^ (acc_7 >>> 47) ^ secretLong[offSec + 8 * 7]) * XXH_PRIME32_1;
    }

    /* last partial block */
    final long nbStripes = ((length - 1) - (block_len * nb_blocks)) / 64;
    final int offBlock = off + block_len * nb_blocks;
    for (int s = 0; s < nbStripes; s++) {
      // accumulate_512
      final int offStripe = offBlock + s * 64;
      final int offSec = s * 8;
      {
        final long data_val_0 = access.i64(input, offStripe);
        final long data_val_1 = access.i64(input, offStripe + 8);
        final long data_key_0 = data_val_0 ^ secretLong[offSec];
        final long data_key_1 = data_val_1 ^ secretLong[offSec + 8];
        /* swap adjacent lanes */
        acc_0 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
        acc_1 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
      }
      {
        final long data_val_0 = access.i64(input, offStripe + 8 * 2);
        final long data_val_1 = access.i64(input, offStripe + 8 * 3);
        final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 2];
        final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 3];
        /* swap adjacent lanes */
        acc_2 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
        acc_3 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
      }
      {
        final long data_val_0 = access.i64(input, offStripe + 8 * 4);
        final long data_val_1 = access.i64(input, offStripe + 8 * 5);
        final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 4];
        final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 5];
        /* swap adjacent lanes */
        acc_4 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
        acc_5 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
      }
      {
        final long data_val_0 = access.i64(input, offStripe + 8 * 6);
        final long data_val_1 = access.i64(input, offStripe + 8 * 7);
        final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 6];
        final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 7];
        /* swap adjacent lanes */
        acc_6 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
        acc_7 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
      }
    }

    /* last stripe */
    // accumulate_512
    final int offStripe = off + length - 64;
    final int offSec = 192 - 64 - 7;
    {
      final long data_val_0 = access.i64(input, offStripe);
      final long data_val_1 = access.i64(input, offStripe + 8);
      final long data_key_0 = data_val_0 ^ secretLong[offSec];
      final long data_key_1 = data_val_1 ^ secretLong[offSec + 8];
      /* swap adjacent lanes */
      acc_0 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
      acc_1 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
    }
    {
      final long data_val_0 = access.i64(input, offStripe + 8 * 2);
      final long data_val_1 = access.i64(input, offStripe + 8 * 3);
      final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 2];
      final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 3];
      /* swap adjacent lanes */
      acc_2 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
      acc_3 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
    }
    {
      final long data_val_0 = access.i64(input, offStripe + 8 * 4);
      final long data_val_1 = access.i64(input, offStripe + 8 * 5);
      final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 4];
      final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 5];
      /* swap adjacent lanes */
      acc_4 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
      acc_5 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
    }
    {
      final long data_val_0 = access.i64(input, offStripe + 8 * 6);
      final long data_val_1 = access.i64(input, offStripe + 8 * 7);
      final long data_key_0 = data_val_0 ^ secretLong[offSec + 8 * 6];
      final long data_key_1 = data_val_1 ^ secretLong[offSec + 8 * 7];
      /* swap adjacent lanes */
      acc_6 += data_val_1 + (0xFFFFFFFFL & data_key_0) * (data_key_0 >>> 32);
      acc_7 += data_val_0 + (0xFFFFFFFFL & data_key_1) * (data_key_1 >>> 32);
    }

    // merge accumulators
    final long result64 = length * XXH_PRIME64_1
                          + mix2Accs(acc_0, acc_1, 11)
                          + mix2Accs(acc_2, acc_3, 11 + 16)
                          + mix2Accs(acc_4, acc_5, 11 + 16 * 2)
                          + mix2Accs(acc_6, acc_7, 11 + 16 * 3);

    return avalanche(result64);
  }
private static <T> long hashLarge(T input, Access<T> access, int off, int length, long seed)