/// <summary> /// Combine two sets of WeighedEntries together based upon the specified matchCombiner. This will throw an exception for any null argument. /// </summary> public static NonNullImmutableList <WeightedEntry <TKey> > CombineResults <TKey>( this NonNullImmutableList <WeightedEntry <TKey> > results, NonNullImmutableList <WeightedEntry <TKey> > resultsToAdd, IEqualityComparer <TKey> keyComparer, MatchCombiner matchCombiner) { if (resultsToAdd == null) { throw new ArgumentNullException("resultsToAdd"); } if (keyComparer == null) { throw new ArgumentNullException("keyComparer"); } if (matchCombiner == null) { throw new ArgumentNullException("matchCombiner"); } return(CombineResults( results, (new[] { resultsToAdd }).ToNonNullImmutableList(), keyComparer, matchCombiner )); }
public QueryTranslator( IIndexData <TKey> standardMatchIndexData, IIndexData <TKey> preciseMatchIndexData, MatchCombiner matchCombiner) : this(standardMatchIndexData, preciseMatchIndexData, null, matchCombiner) { }
public QueryTranslator( IIndexData <TKey> standardMatchIndexData, IIndexData <TKey> preciseMatchIndexData, ITokenBreaker optionalQuotedValueConsecutiveTermTokenBreaker, MatchCombiner matchCombiner) : this(standardMatchIndexData, preciseMatchIndexData, optionalQuotedValueConsecutiveTermTokenBreaker, null, null, matchCombiner) { }
/// <summary> /// Combine multiple sets of WeighedEntries together based upon the specified matchCombiner. This will throw an exception for any null argument. /// </summary> public static NonNullImmutableList <WeightedEntry <TKey> > CombineResults <TKey>( this NonNullImmutableList <WeightedEntry <TKey> > results, NonNullImmutableList <NonNullImmutableList <WeightedEntry <TKey> > > resultSetsToAdd, IEqualityComparer <TKey> keyComparer, MatchCombiner matchCombiner) { if (results == null) { throw new ArgumentNullException("results"); } if (resultSetsToAdd == null) { throw new ArgumentNullException("resultSetsToAdd"); } if (keyComparer == null) { throw new ArgumentNullException("keyComparer"); } if (matchCombiner == null) { throw new ArgumentNullException("matchCombiner"); } var allMatchesByKey = new Dictionary <TKey, List <WeightedEntry <TKey> > >( keyComparer ); foreach (var resultSet in resultSetsToAdd.Add(results)) { foreach (var result in resultSet) { if (!allMatchesByKey.ContainsKey(result.Key)) { allMatchesByKey.Add(result.Key, new List <WeightedEntry <TKey> >()); } allMatchesByKey[result.Key].Add(result); } } var combinedData = new List <WeightedEntry <TKey> >(); foreach (var match in allMatchesByKey) { var weight = matchCombiner(match.Value.Select(v => v.Weight).ToImmutableList()); if (weight <= 0) { throw new Exception("matchCombiner return weight of zero or less - invalid"); } combinedData.Add(new WeightedEntry <TKey>( match.Key, weight, match.Value.Any(v => v.SourceLocationsIfRecorded == null) ? null : match.Value.SelectMany(v => v.SourceLocationsIfRecorded).ToNonNullImmutableList() )); } return(combinedData.ToNonNullImmutableList()); }
public QueryTranslator( IIndexData <TKey> standardMatchIndexData, IIndexData <TKey> preciseMatchIndexData, ITokenBreaker optionalQuotedValueConsecutiveTermTokenBreaker, IndexGenerator.WeightedEntryCombiner optionalQuotedValueConsecutiveWeightCombinerForConsecutiveRuns, IndexGenerator.WeightedEntryCombiner optionalQuotedValueConsecutiveWeightCombinerForFinalMatches, MatchCombiner matchCombiner) { if (standardMatchIndexData == null) { throw new ArgumentNullException("standardMatchIndexData"); } if (preciseMatchIndexData == null) { throw new ArgumentNullException("preciseMatchIndexData"); } if (matchCombiner == null) { throw new ArgumentNullException("matchCombiner"); } if (!preciseMatchIndexData.SourceLocationsAvailable) { throw new ArgumentException($"The {nameof(preciseMatchIndexData)} must include source location data in order to use the Query Translator"); } // Can't actually determine for sure that the KeyComparer of the standardMatchIndexData is equivalent to that of the preciseMatchIndexData // (can't do an instance comparison since they may be different instances of the same implementation, they could even feasibly be different // classes with identical functionality) so we'll have to assume that the caller is behaving themselves. We'll take the KeyComparer of the // standardMatchIndexData for use when combining keys, excluding keys or otherwise processing the query segment requirements. _standardMatcher = new CachingResultMatcher(standardMatchIndexData.GetMatches); _preciseMatcher = new CachingResultMatcher( source => preciseMatchIndexData.GetConsecutiveMatches( source, optionalQuotedValueConsecutiveTermTokenBreaker ?? IndexData_Extensions_ConsecutiveMatches.DefaultTokenBreaker, optionalQuotedValueConsecutiveWeightCombinerForConsecutiveRuns ?? IndexData_Extensions_ConsecutiveMatches.DefaultConsecutiveRunsWeightCombiner, optionalQuotedValueConsecutiveWeightCombinerForFinalMatches ?? IndexData_Extensions_ConsecutiveMatches.DefaultFinalMatchWeightCombiner ) ); _keyComparer = standardMatchIndexData.KeyComparer; _matchCombiner = matchCombiner; }