public SuffixArrayRange(PrecomputedSearchResult precomputedResult, IBigArray <ulong> suffixArray, FourBitDigitBigArray digits) { //If there are no results if (precomputedResult.MinSuffixArrayIdx == precomputedResult.MaxSuffixArrayIdx) { HasResults = false; } else //Otherwise there are search results { HasResults = true; Min = precomputedResult.MinSuffixArrayIdx; //Note that the precomputed results are stored with the max value exclusive so that it can also encode HasResults // whereas this class uses inclusive, so correct for that by taking 1 Max = precomputedResult.MaxSuffixArrayIdx - 1; SuffixArray = suffixArray; Digits = digits; } }
public static SuffixArrayRange Search(IBigArray <ulong> suffixArray, FourBitDigitBigArray digitArray, byte[] lookFor, IBigArray <PrecomputedSearchResult>[] precomputedResults = null) { //Validation if (lookFor.Length == 0) { throw new ArgumentException("lookFor must contain at least 1 digit"); } if (digitArray.Length == 0) { return(new SuffixArrayRange(false)); } if (suffixArray.Length != digitArray.Length) { throw new ArgumentException( "Suffix Array must be the same length as the Digit Array. This is not the correct suffix array for this digit array"); } //If we've been passed null for the precomputedResults, make an empty array for them if (precomputedResults == null) { precomputedResults = new IBigArray <PrecomputedSearchResult> [0]; } //If we have been given the precomputed results for strings of the length we're looking for if (precomputedResults.Length >= lookFor.Length) { IBigArray <PrecomputedSearchResult> precomputedResultsOfRequiredLength = precomputedResults[lookFor.Length - 1]; //Convert the string of bytes we're looking for to a long to use as the array index long precomputedResultIdx = ByteArrToLong(lookFor); PrecomputedSearchResult precomputedResult = precomputedResultsOfRequiredLength[precomputedResultIdx]; //Convert this precomputed result into a SuffixArrayRange before returning it SuffixArrayRange suffixArrayRange = new SuffixArrayRange(precomputedResult, suffixArray, digitArray); return(suffixArrayRange); } else //Otherwise we don't have the precomputed results for this search, run the suffix array search { long matchingPosition = binarySearchForPrefix(suffixArray, digitArray, lookFor, 0, suffixArray.Length - 1); //If there were no matches if (matchingPosition == -1) { return(new SuffixArrayRange(false)); } else //Otherwise match found, look for more { long min = matchingPosition; long max = matchingPosition; while (min > 0 && doesStartWithSuffix(digitArray, lookFor, (long)suffixArray[min - 1]) == 0) { min--; } while (max < digitArray.Length - 1 && doesStartWithSuffix(digitArray, lookFor, (long)suffixArray[max + 1]) == 0) { max++; } SuffixArrayRange suffixArrayRange = new SuffixArrayRange(min, max, suffixArray, digitArray); return(suffixArrayRange); } } }