예제 #1
0
 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;
     }
 }
예제 #2
0
        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);
                }
            }
        }