/// <summary> /// Add an element to the tree respecting a size limit /// </summary> /// <param name="results"> the tree to add in </param> /// <param name="result"> the result we try to add </param> /// <param name="num"> size limit </param> private static void BoundedTreeAdd(JCG.SortedSet <Lookup.LookupResult> results, Lookup.LookupResult result, int num) { if (results.Count >= num) { if (results.Min.Value < result.Value) { lock (syncLock) { if (results.Min.Value < result.Value) { // Code similar to the java TreeMap class var entry = results.FirstOrDefault(); if (entry != null) { results.Remove(entry); } } else { return; } } } else { return; } } results.Add(result); }
/// <summary> /// Add an element to the tree respecting a size limit /// </summary> /// <param name="results"> the tree to add in </param> /// <param name="result"> the result we try to add </param> /// <param name="num"> size limit </param> private static void BoundedTreeAdd(JCG.SortedSet <Lookup.LookupResult> results, Lookup.LookupResult result, int num) { if (results.Count >= num) { var first = results.Min; // "get" our first object so we don't cross threads if (first.Value < result.Value) { // Code similar to the java TreeMap class results.Remove(first); } else { return; } } results.Add(result); }
protected internal override IList <Lookup.LookupResult> CreateResults(IndexSearcher searcher, TopFieldDocs hits, int num, string key, bool doHighlight, ICollection <string> matchedTokens, string prefixToken) { BinaryDocValues textDV = MultiDocValues.GetBinaryValues(searcher.IndexReader, TEXT_FIELD_NAME); Debug.Assert(textDV != null); // This will just be null if app didn't pass payloads to build(): // TODO: maybe just stored fields? they compress... BinaryDocValues payloadsDV = MultiDocValues.GetBinaryValues(searcher.IndexReader, "payloads"); JCG.SortedSet <Lookup.LookupResult> results = new JCG.SortedSet <Lookup.LookupResult>(LOOKUP_COMP); // we reduce the num to the one initially requested int actualNum = num / numFactor; BytesRef scratch = new BytesRef(); for (int i = 0; i < hits.ScoreDocs.Length; i++) { FieldDoc fd = (FieldDoc)hits.ScoreDocs[i]; textDV.Get(fd.Doc, scratch); string text = scratch.Utf8ToString(); long weight = (long)fd.Fields[0]; BytesRef payload; if (payloadsDV != null) { payload = new BytesRef(); payloadsDV.Get(fd.Doc, payload); } else { payload = null; } double coefficient; if (text.StartsWith(key.ToString(), StringComparison.Ordinal)) { // if hit starts with the key, we don't change the score coefficient = 1; } else { coefficient = CreateCoefficient(searcher, fd.Doc, matchedTokens, prefixToken); } long score = (long)(weight * coefficient); LookupResult result; if (doHighlight) { object highlightKey = Highlight(text, matchedTokens, prefixToken); result = new LookupResult(highlightKey.ToString(), highlightKey, score, payload); } else { result = new LookupResult(text, score, payload); } BoundedTreeAdd(results, result, actualNum); } return(new List <LookupResult>(results.Reverse())); }