예제 #1
0
        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))
                                    {
                                        break;
                                    }
                                    if (reader.IsDeleted(termDocs.Doc))
                                    {
                                        break;
                                    }
                                    if (docIds.Contains(termDocs.Doc) == false)
                                    {
                                        break;
                                    }

                                    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();
            }
        }