/// <summary>
            /// Adapted from https://github.com/google/brotli/blob/master/c/enc/compress_fragment.c (BrotliCompressFragmentFastImpl, two occurrences).
            /// </summary>
            public int UpdateAndGetCandidate(int ip, int baseIp)
            {
                ulong inputBytes = HasherCommon.Load64LE(input, ip - 3);
                uint  prevHash   = HashBytesAtOffset(inputBytes, 0, shift);
                uint  curHash    = HashBytesAtOffset(inputBytes, 3, shift);

                table[prevHash] = ip - baseIp - 3;
                prevHash        = HashBytesAtOffset(inputBytes, 1, shift);
                table[prevHash] = ip - baseIp - 2;
                prevHash        = HashBytesAtOffset(inputBytes, 2, shift);
                table[prevHash] = ip - baseIp - 1;

                int candidate = baseIp + table[curHash];

                table[curHash] = ip - baseIp;
                return(candidate);
            }
            /// <summary>
            /// Adapted from https://github.com/google/brotli/blob/master/c/enc/compress_fragment.c (Hash).
            /// </summary>
            private static uint Hash(byte[] bytes, int index, int shift)
            {
                ulong h = unchecked ((HasherCommon.Load64LE(bytes, index) << 24) * HashMul32);

                return((uint)(h >> shift));
            }