public static void ReadEntriesForFields( IndexSearcherHolder.IndexSearcherHoldingState state, HashSet <string> fieldsToRead, HashSet <int> docIds, Action <string, string, int> onTermFound) { var reader = state.IndexSearcher.IndexReader; state.Lock.EnterReadLock(); try { EnsureFieldsAreInCache(state, fieldsToRead, reader); foreach (var field in fieldsToRead) { foreach (var docId in docIds) { foreach (var term in state.GetTermsFromCache(field, docId)) { onTermFound(term.Field, term.Text, docId); } } } } finally { if (state.Lock.IsReadLockHeld) { state.Lock.ExitReadLock(); } } }
public static void ReadEntriesForFields( IndexSearcherHolder.IndexSearcherHoldingState state, HashSet <string> fieldsToRead, HashSet <int> docIds, Action <Term, 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 term in state.GetTermsFromCache(field, docId)) { read.Add(docId); onTermFound(term, 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); } state.SetInCache(field, termDocs.Doc, termEnum.Term); onTermFound(termEnum.Term, termDocs.Doc); } } while (termEnum.Next()); } } } } finally { state.Lock.ExitWriteLock(); } }