public override TopFieldDocs Search(Weight weight, Filter filter, int n, Sort sort, IState state) { var hq = new FieldDocSortedHitQueue(n); int totalHits = 0; float maxScore = System.Single.NegativeInfinity; var lockObj = new object(); for (int i = 0; i < searchables.Length; i++) { // search each searcher // use NullLock, we don't care about synchronization for these TopFieldDocs docs = MultiSearcherCallableWithSort(ThreadLock.NullLock, lockObj, searchables[i], weight, filter, n, hq, sort, i, starts, state); totalHits += docs.TotalHits; maxScore = System.Math.Max(maxScore, docs.MaxScore); } ScoreDoc[] scoreDocs2 = new ScoreDoc[hq.Size()]; for (int i = hq.Size() - 1; i >= 0; i--) { // put docs in array scoreDocs2[i] = hq.Pop(); } return(new TopFieldDocs(totalHits, scoreDocs2, hq.GetFields(), maxScore)); }
/// <summary> A search implementation allowing sorting which spans a new thread for each /// Searchable, waits for each search to complete and merges /// the results back together. /// </summary> public override TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort) { if (sort == null) { throw new ArgumentNullException("sort"); } FieldDocSortedHitQueue hq = new FieldDocSortedHitQueue(nDocs); object lockObj = new object(); TopFieldDocs[] results = new TopFieldDocs[searchables.Length]; Parallel.For(0, searchables.Length, (i) => results[i] = MultiSearcherCallableWithSort(ThreadLock.MonitorLock, lockObj, searchables[i], weight, filter, nDocs, hq, sort, i, starts)); int totalHits = 0; float maxScore = float.NegativeInfinity; foreach (TopFieldDocs topFieldDocs in results) { totalHits += topFieldDocs.TotalHits; maxScore = Math.Max(maxScore, topFieldDocs.MaxScore); } ScoreDoc[] scoreDocs = new ScoreDoc[hq.Size()]; for (int i = hq.Size() - 1; i >= 0; i--) { scoreDocs[i] = hq.Pop(); } return(new TopFieldDocs(totalHits, scoreDocs, hq.GetFields(), maxScore)); }
override public void Run() { try { docs = (sort == null)?searchable.Search(weight, filter, nDocs):searchable.Search(weight, filter, nDocs, sort); } // Store the IOException for later use by the caller of this thread catch (System.Exception e) { this.ioe = e; } if (this.ioe == null) { // if we are sorting by fields, we need to tell the field sorted hit queue // the actual type of fields, in case the original list contained AUTO. // if the searchable returns null for fields, we'll have problems. if (sort != null) { TopFieldDocs docsFields = (TopFieldDocs)docs; // If one of the Sort fields is FIELD_DOC, need to fix its values, so that // it will break ties by doc Id properly. Otherwise, it will compare to // 'relative' doc Ids, that belong to two different searchables. for (int j = 0; j < docsFields.fields.Length; j++) { if (docsFields.fields[j].GetType() == SortField.DOC) { // iterate over the score docs and change their fields value for (int j2 = 0; j2 < docs.ScoreDocs.Length; j2++) { FieldDoc fd = (FieldDoc)docs.ScoreDocs[j2]; //DIGY?? No unit test for the line below fd.fields[j] = (System.Int32)(((System.Int32)fd.fields[j]) + starts[i]); } break; } } ((FieldDocSortedHitQueue)hq).SetFields(docsFields.fields); } ScoreDoc[] scoreDocs = docs.ScoreDocs; for (int j = 0; j < scoreDocs.Length; j++) { // merge scoreDocs into hq ScoreDoc scoreDoc = scoreDocs[j]; scoreDoc.Doc += starts[i]; // convert doc //it would be so nice if we had a thread-safe insert lock (hq) { if (!hq.Insert(scoreDoc)) { break; } } // no more scores > minScore } } }
public override TopFieldDocs Search(Weight weight, Filter filter, int n, Sort sort) { FieldDocSortedHitQueue hq = null; int totalHits = 0; float maxScore = System.Single.NegativeInfinity; for (int i = 0; i < searchables.Length; i++) { // search each searcher TopFieldDocs docs = searchables[i].Search(weight, filter, n, sort); // If one of the Sort fields is FIELD_DOC, need to fix its values, so that // it will break ties by doc Id properly. Otherwise, it will compare to // 'relative' doc Ids, that belong to two different searchers. for (int j = 0; j < docs.fields.Length; j++) { if (docs.fields[j].GetType() == SortField.DOC) { // iterate over the score docs and change their fields value for (int j2 = 0; j2 < docs.scoreDocs.Length; j2++) { FieldDoc fd = (FieldDoc)docs.scoreDocs[j2]; fd.fields[j] = (System.Int32)(((System.Int32)fd.fields[j]) + starts[i]); } break; } } if (hq == null) { hq = new FieldDocSortedHitQueue(docs.fields, n); } totalHits += docs.totalHits; // update totalHits maxScore = System.Math.Max(maxScore, docs.GetMaxScore()); ScoreDoc[] scoreDocs = docs.scoreDocs; for (int j = 0; j < scoreDocs.Length; j++) { // merge scoreDocs into hq ScoreDoc scoreDoc = scoreDocs[j]; scoreDoc.doc += starts[i]; // convert doc if (!hq.Insert(scoreDoc)) { break; // no more scores > minScore } } } ScoreDoc[] scoreDocs2 = new ScoreDoc[hq.Size()]; for (int i = hq.Size() - 1; i >= 0; i--) { // put docs in array scoreDocs2[i] = (ScoreDoc)hq.Pop(); } return(new TopFieldDocs(totalHits, scoreDocs2, hq.GetFields(), maxScore)); }
/// <summary> /// Just like <seealso cref="#search(Weight, int, Sort, boolean, boolean)"/>, but you choose /// whether or not the fields in the returned <seealso cref="FieldDoc"/> instances should /// be set by specifying fillFields. /// </summary> protected internal virtual TopFieldDocs Search(Weight weight, FieldDoc after, int nDocs, Sort sort, bool fillFields, bool doDocScores, bool doMaxScore) { if (sort == null) { throw new System.NullReferenceException("Sort must not be null"); } int limit = Reader.MaxDoc; if (limit == 0) { limit = 1; } nDocs = Math.Min(nDocs, limit); if (Executor == null) { // use all leaves here! return(Search(LeafContexts, weight, after, nDocs, sort, fillFields, doDocScores, doMaxScore)); } else { TopFieldCollector topCollector = TopFieldCollector.Create(sort, nDocs, after, fillFields, doDocScores, doMaxScore, false); ReentrantLock @lock = new ReentrantLock(); ExecutionHelper <TopFieldDocs> runner = new ExecutionHelper <TopFieldDocs>(Executor); for (int i = 0; i < LeafSlices.Length; i++) // search each leaf slice { runner.Submit(new SearcherCallableWithSort(@lock, this, LeafSlices[i], weight, after, nDocs, topCollector, sort, doDocScores, doMaxScore)); } int totalHits = 0; float maxScore = float.NegativeInfinity; foreach (TopFieldDocs topFieldDocs in runner) { if (topFieldDocs.TotalHits != 0) { totalHits += topFieldDocs.TotalHits; maxScore = Math.Max(maxScore, topFieldDocs.MaxScore); } } TopFieldDocs topDocs = (TopFieldDocs)topCollector.TopDocs(); return(new TopFieldDocs(totalHits, topDocs.ScoreDocs, topDocs.Fields, topDocs.MaxScore)); } }
public override TopFieldDocs Search(Weight weight, Filter filter, int n, Sort sort) { FieldDocSortedHitQueue hq = null; int totalHits = 0; float maxScore = System.Single.NegativeInfinity; for (int i = 0; i < searchables.Length; i++) { // search each searcher TopFieldDocs docs = searchables[i].Search(weight, filter, n, sort); if (hq == null) { hq = new FieldDocSortedHitQueue(docs.fields, n); } totalHits += docs.totalHits; // update totalHits maxScore = System.Math.Max(maxScore, docs.GetMaxScore()); ScoreDoc[] scoreDocs = docs.scoreDocs; for (int j = 0; j < scoreDocs.Length; j++) { // merge scoreDocs into hq ScoreDoc scoreDoc = scoreDocs[j]; scoreDoc.doc += starts[i]; // convert doc if (!hq.Insert(scoreDoc)) { break; // no more scores > minScore } } } ScoreDoc[] scoreDocs2 = new ScoreDoc[hq.Size()]; for (int i = hq.Size() - 1; i >= 0; i--) { // put docs in array scoreDocs2[i] = (ScoreDoc)hq.Pop(); } return(new TopFieldDocs(totalHits, scoreDocs2, hq.GetFields(), maxScore)); }
/// <summary> A search implementation allowing sorting which spans a new thread for each /// Searchable, waits for each search to complete and merges /// the results back together. /// </summary> public override TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort) { if (sort == null) throw new ArgumentNullException("sort"); FieldDocSortedHitQueue hq = new FieldDocSortedHitQueue(nDocs); object lockObj = new object(); TopFieldDocs[] results = new TopFieldDocs[searchables.Length]; Parallel.For(0, searchables.Length, (i) => results[i] = MultiSearcherCallableWithSort(ThreadLock.MonitorLock, lockObj, searchables[i], weight, filter, nDocs, hq, sort, i, starts)); int totalHits = 0; float maxScore = float.NegativeInfinity; foreach (TopFieldDocs topFieldDocs in results) { totalHits += topFieldDocs.TotalHits; maxScore = Math.Max(maxScore, topFieldDocs.MaxScore); } ScoreDoc[] scoreDocs = new ScoreDoc[hq.Size()]; for (int i = hq.Size() - 1; i >= 0; i--) scoreDocs[i] = hq.Pop(); return new TopFieldDocs(totalHits, scoreDocs, hq.GetFields(), maxScore); }