/// <summary> /// Perform lookup for byte string at position. /// </summary> /// <param name="src">Source buffer.</param> /// <param name="position">Position in source buffer.</param> /// <param name="window">Deltas window.</param> /// <param name="recents">Recents buffer.</param> /// <returns></returns> static LookupResult Lookup( ReadOnlySpan <byte> src, int position, ref RevolvingBufferTracker <int> window, Span <int> recents) { // Get offset to previous index of current byte value. var c = src[position]; var recent = recents[c] - 1; // Check if: recent is 0 (no previous byte with this value), or offset is out-of-range of window. if (recent < 0 || window.Length < (position - recent)) { return(LookupResult.NoneFound()); } else { // Start searching at recent position. var searchPosition = recent; var currentSlice = src.Slice(position, Math.Min(MaxCompare, src.Length - position)); var windowStartPosition = Math.Max(position - window.Length, 0); var result = LookupResult.NoneFound(); // Follow chain backwards and look for matches. while (windowStartPosition <= searchPosition) { // Get slice for bytes to compare against currentSlice var searchSlice = src.Slice(searchPosition); // Find number of potential matches in search slice. var potentialMatches = Math.Min(currentSlice.Length, searchSlice.Length); // Set matches count to maximum, will update if loop exits early. var matches = potentialMatches; for (int i = 0; i < potentialMatches; i++) { if (currentSlice[i] != searchSlice[i]) { matches = i; break; } } // Update lookup result if found new longest match. if (matches >= 3 && matches >= result.Length) { result = new LookupResult(searchPosition, matches); // If we have found a matching string with the max compare size, return early. if (result.Length == MaxCompare) { break; } } // Get search position relative to window start, and update search position. var windowIndex = searchPosition - windowStartPosition; searchPosition = window.Get(windowIndex); // If next index is less-than 0, no previous instance of this value. if (searchPosition < 0) { break; } } return(result); } }