protected override HasherSearchResult.BackReferenceBuilder FindLongestBackReference(int ip, int maxLength, int maxDistance, int lastDistance, int bestLenIn)
            {
                byte compareChar = input[ip + bestLenIn];
                uint key         = HashBytes(input, ip);

                var result = new HasherSearchResult.BackReferenceBuilder {
                    Len = bestLenIn
                };

                int bestScore = result.Score;
                int bestLen   = result.Len;

                int cachedBackward = lastDistance;
                int prevIp         = ip - cachedBackward;

                if (prevIp < ip && prevIp >= 0 && compareChar == input[prevIp + bestLen])
                {
                    int len = Match.DetermineLength(input, prevIp, ip, maxLength);

                    if (len >= 4)
                    {
                        int score = HasherSearchResult.BackwardReferenceScoreUsingLastDistance(len);

                        if (bestScore < score)
                        {
                            result.Len      = len;
                            result.Distance = cachedBackward;
                            result.Score    = score;

                            bestLen     = len;
                            bestScore   = score;
                            compareChar = input[ip + len];
                        }
                    }
                }

                var keys = new uint[sweep];

                for (int i = 0; i < sweep; i++)
                {
                    keys[i] = (uint)((key + (i << 3)) & bucketMask);
                }

                uint keyOut = keys[(ip & sweepMask) >> 3];

                for (int i = 0; i < sweep; i++)
                {
                    prevIp = table[keys[i]];

                    int backward = ip - prevIp;

                    if (compareChar != input[prevIp + bestLen])
                    {
                        continue;
                    }

                    if (backward == 0 || backward > maxDistance)
                    {
                        continue;
                    }

                    int len = Match.DetermineLength(input, prevIp, ip, maxLength);

                    if (len >= 4)
                    {
                        int score = HasherSearchResult.BackwardReferenceScore(len, backward);

                        if (bestScore < score)
                        {
                            result.Len      = bestLen = len;
                            result.Score    = bestScore = score;
                            result.Distance = backward;

                            compareChar = input[ip + len];
                        }
                    }
                }

                table[keyOut] = ip;
                return(result);
            }
            protected override HasherSearchResult.BackReferenceBuilder FindLongestBackReference(int ip, int maxLength, int maxDistance, int lastDistance, int bestLenIn)
            {
                byte compareChar = input[ip + bestLenIn];
                uint key         = HashBytes(input, ip);

                var result = new HasherSearchResult.BackReferenceBuilder {
                    Len = bestLenIn
                };

                int bestScore = result.Score;
                int bestLen   = result.Len;

                int cachedBackward = lastDistance;
                int prevIp         = ip - cachedBackward;
                int len;

                if (prevIp < ip && prevIp >= 0 && compareChar == input[prevIp + bestLen])
                {
                    len = Match.DetermineLength(input, prevIp, ip, maxLength);

                    if (len >= 4)
                    {
                        int score = HasherSearchResult.BackwardReferenceScoreUsingLastDistance(len);

                        if (bestScore < score)
                        {
                            result.Len      = len;
                            result.Distance = cachedBackward;
                            result.Score    = score;

                            table[key] = ip;
                            return(result);
                        }
                    }
                }

                prevIp     = table[key];
                table[key] = ip;

                int backward = ip - prevIp;

                if (compareChar != input[prevIp + bestLenIn])
                {
                    return(result);
                }

                if (backward == 0 || backward > maxDistance)
                {
                    return(result);
                }

                len = Match.DetermineLength(input, prevIp, ip, maxLength);

                if (len >= 4)
                {
                    int score = HasherSearchResult.BackwardReferenceScore(len, backward);

                    if (bestScore < score)
                    {
                        result.Len      = len;
                        result.Score    = score;
                        result.Distance = backward;
                        return(result);
                    }
                }

                return(result);
            }