private static void FillCache(IndexSearcherHolder.IndexSearcherHoldingState state, IEnumerable<string> fieldsToRead,IndexReader reader) { foreach (var field in fieldsToRead) { var items = new LinkedList<IndexSearcherHolder.IndexSearcherHoldingState.CacheVal>[reader.MaxDoc]; using (var termDocs = reader.TermDocs()) { using (var termEnum = reader.Terms(new Term(field))) { do { if (termEnum.Term == null || field != termEnum.Term.Field) break; Term term = termEnum.Term; if (LowPrecisionNumber(term.Field, term.Text)) continue; var totalDocCountIncludedDeletes = termEnum.DocFreq(); termDocs.Seek(termEnum.Term); while (termDocs.Next() && totalDocCountIncludedDeletes > 0) { totalDocCountIncludedDeletes -= 1; if (reader.IsDeleted(termDocs.Doc)) continue; if(items[termDocs.Doc] == null) items[termDocs.Doc] = new LinkedList<IndexSearcherHolder.IndexSearcherHoldingState.CacheVal>(); items[termDocs.Doc].AddLast(new IndexSearcherHolder.IndexSearcherHoldingState.CacheVal { Term = termEnum.Term }); } } while (termEnum.Next()); } } state.SetInCache(field, items); } }
public static void ReadEntriesForFields( IndexSearcherHolder.IndexSearcherHoldingState state, HashSet<string> fieldsToRead, HashSet<int> docIds, Func<Term, double> convert, Action<Term, double, int> onTermFound) { var reader = state.IndexSearcher.IndexReader; var readFromCache = new Dictionary<string, HashSet<int>>(); state.Lock.EnterReadLock(); try { foreach (var field in fieldsToRead) { var read = new HashSet<int>(); readFromCache[field] = read; foreach (var docId in docIds) { foreach (var val in state.GetFromCache(field, docId)) { read.Add(docId); double converted; if (val.Val == null) { val.Val = converted = convert(val.Term); } else { converted = val.Val.Value; } onTermFound(val.Term, converted, docId); } } } } finally { state.Lock.ExitReadLock(); } foreach (var kvp in readFromCache) { if (kvp.Value.Count == docIds.Count) { fieldsToRead.Remove(kvp.Key); // already read all of it } } if (fieldsToRead.Count == 0) return; state.Lock.EnterWriteLock(); try { using (var termDocs = reader.TermDocs()) { foreach (var field in fieldsToRead) { var read = readFromCache[field]; var shouldReset = new HashSet<Tuple<string, int>>(); using (var termEnum = reader.Terms(new Term(field))) { do { if (termEnum.Term == null || field != termEnum.Term.Field) break; if (LowPrecisionNumber(termEnum.Term)) continue; var totalDocCountIncludedDeletes = termEnum.DocFreq(); termDocs.Seek(termEnum.Term); while (termDocs.Next() && totalDocCountIncludedDeletes > 0) { totalDocCountIncludedDeletes -= 1; if (read.Contains(termDocs.Doc)) continue; if (reader.IsDeleted(termDocs.Doc)) continue; if (docIds.Contains(termDocs.Doc) == false) continue; if (shouldReset.Add(Tuple.Create(field, termDocs.Doc))) { state.ResetInCache(field, termDocs.Doc); } var d = convert(termEnum.Term); state.SetInCache(field, termDocs.Doc, termEnum.Term, d); onTermFound(termEnum.Term, d, termDocs.Doc); } } while (termEnum.Next()); } } } } finally { state.Lock.ExitWriteLock(); } }
private static void FillCache(IndexSearcherHolder.IndexSearcherHoldingState state, List<string> fieldsToRead,IndexReader reader) { foreach (var field in fieldsToRead) { using (var termDocs = reader.TermDocs()) { using (var termEnum = reader.Terms(new Term(field))) { do { if (termEnum.Term == null || field != termEnum.Term.Field) break; if (LowPrecisionNumber(termEnum.Term)) continue; var totalDocCountIncludedDeletes = termEnum.DocFreq(); termDocs.Seek(termEnum.Term); while (termDocs.Next() && totalDocCountIncludedDeletes > 0) { totalDocCountIncludedDeletes -= 1; if (reader.IsDeleted(termDocs.Doc)) continue; state.SetInCache(field, termDocs.Doc, termEnum.Term); } } while (termEnum.Next()); } } } }