Ejemplo n.º 1
0
        public IList <LuceneResult> Search(Query query, SortField sortField, int limit, int offset, float threshold, LuceneProfiler profiler, Plug authPlug)
        {
            return(_disposalLock.ExecuteWithReadLock(() => {
                using (profiler.ProfileQueryInternals()) {
                    EnsureInstanceNotDisposed();
                    var searcher = GetSearcher();
                    int numHits;
                    if (authPlug == null)
                    {
                        numHits = Math.Min(searcher.MaxDoc(), limit == int.MaxValue ? int.MaxValue : limit + offset);
                    }
                    else
                    {
                        var setSizeGuessLong = ((long)offset + limit) * 5;
                        setSizeGuessLong = Math.Max(1000, setSizeGuessLong);
                        var setSizeGuess = setSizeGuessLong.ToInt();
                        numHits = Math.Min(searcher.MaxDoc(), setSizeGuess);
                    }
                    var collector = TopFieldCollector.create(
                        sortField == null ? new Sort() : new Sort(sortField),
                        numHits,
                        false,            // fillFields, not required
                        true,             // trackDocScores, required
                        true,             // trackMaxScore, related to trackDocScores
                        sortField == null // should docs be in docId order?
                        );
                    searcher.Search(query, collector);
                    var docs = collector.TopDocs();
                    var maxscore = docs.GetMaxScore();

                    // Note: cheap way to avoid div/zero
                    if (maxscore == 0)
                    {
                        maxscore = 1;
                    }
                    var items = from hit in docs.scoreDocs
                                let score = hit.score / maxscore
                                            where score >= threshold
                                            select new LuceneResult(searcher.Doc(hit.doc), score);
                    IList <LuceneResult> resultSet;
                    if (authPlug == null)
                    {
                        if (offset > 0 || limit != int.MaxValue)
                        {
                            items = items.Skip(offset).Take(limit);
                        }
                        resultSet = items.ToList();
                    }
                    else
                    {
                        resultSet = LuceneResultFilter.Filter(authPlug, items, offset, limit, new Result <IList <LuceneResult> >()).Wait();
                    }
                    return resultSet;
                }
            }));
        }
Ejemplo n.º 2
0
 //--- Class Methods ---
 public static Result<IList<LuceneResult>> Filter(Plug authPlug, IEnumerable<LuceneResult> items, int offset, int limit, Result<IList<LuceneResult>> result) {
     var builder = new LuceneResultFilter(authPlug, 10000, 100);
     return Coroutine.Invoke(builder.Filter, items, offset, limit, result);
 }
Ejemplo n.º 3
0
        public void Limit_smaller_than_item_set_forces_authorization_in_chunks_as_candidates_nears_limit() {
            var items = new List<LuceneResult>();
            for(var i = 1; i <= 200; i++) {
                items.Add(Result(i));
            }

            // first chunk should ask for 50 ids and we'll filter 20 from that set
            MockPlug.Setup(_authUri)
                .Verb("POST")
                .WithMessage(m => {
                    var t = m.ToText();
                    var match = t.EqualsInvariant(items.Select(x => x.PageId.Value).Take(50).ToCommaDelimitedString());
                    _log.DebugFormat("first chunk match? {0} => {1}", match, t);
                    return match;
                })
                .Returns(DreamMessage.Ok(MimeType.TEXT, S(10,39).ToCommaDelimitedString()))
                .ExpectCalls(Times.Once());

            // second chunk should ask for 30 and we'll filter 5 from that set
            // which gives it a total larger than our limit, i.e. it won't try for a third chunk
            MockPlug.Setup(_authUri)
                .Verb("POST")
                .WithMessage(m => {
                    var t = m.ToText();
                    var match = t.EqualsInvariant(items.Select(x => x.PageId.Value).Skip(50).Take(30).ToCommaDelimitedString());
                    _log.DebugFormat("second chunk match? {0} => {1}", match, t);
                    return match;
                })
                .Returns(DreamMessage.Ok(MimeType.TEXT, S(51,55).ToCommaDelimitedString()))
                .ExpectCalls(Times.Once());
            var builder = new LuceneResultFilter(_authPlug, 10000, 20);
            var set = Coroutine.Invoke(builder.Filter, items, 0, 30, new Result<IList<LuceneResult>>()).Wait();
            Assert.AreEqual(30, set.Count);

            // we expect a sequence of 1-9,40-50,56-... and take the first 30
            var expected = S(1, 9).Union(S(40, 50)).Union(S(56, 100)).Take(30);
            Assert.AreEqual(
                expected.ToCommaDelimitedString(),
                set.Select(x => x.PageId.Value).ToCommaDelimitedString()
            );
            MockPlug.VerifyAll(1.Seconds());
        }
Ejemplo n.º 4
0
 public void Item_sets_larger_than_maxAuthItems_are_authorized_in_chunks() {
     var items = new List<LuceneResult>();
     for(var i = 1; i <= 50; i++) {
         items.Add(Result(i));
     }
     MockPlug.Setup(_authUri)
         .Verb("POST")
         .WithMessage(m => {
             var t = m.ToText();
             var match = t.EqualsInvariant(items.Select(x => x.PageId.Value).Take(30).ToCommaDelimitedString());
             _log.DebugFormat("first chunk match? {0} => {1}", match, t);
             return match;
         })
         .Returns(DreamMessage.Ok(MimeType.TEXT, ""))
         .ExpectCalls(Times.Once());
     MockPlug.Setup(_authUri)
         .Verb("POST")
         .WithMessage(m => {
             var t = m.ToText();
             var match = t.EqualsInvariant(items.Select(x => x.PageId.Value).Skip(30).ToCommaDelimitedString());
             _log.DebugFormat("second chunk match? {0} => {1}", match, t);
             return match;
         })
         .Returns(DreamMessage.Ok(MimeType.TEXT, ""))
         .ExpectCalls(Times.Once());
     var builder = new LuceneResultFilter(_authPlug, 30, 1000);
     var set = Coroutine.Invoke(builder.Filter, items, 0, int.MaxValue, new Result<IList<LuceneResult>>()).Wait();
     Assert.AreEqual(items.Count, set.Count);
     Assert.AreEqual(
         items.Select(x => x.PageId.Value).ToCommaDelimitedString(),
         set.Select(x => x.PageId.Value).ToCommaDelimitedString()
     );
     MockPlug.VerifyAll(1.Seconds());
 }
Ejemplo n.º 5
0
        //--- Class Methods ---
        public static Result <IList <LuceneResult> > Filter(Plug authPlug, IEnumerable <LuceneResult> items, int offset, int limit, Result <IList <LuceneResult> > result)
        {
            var builder = new LuceneResultFilter(authPlug, 10000, 100);

            return(Coroutine.Invoke(builder.Filter, items, offset, limit, result));
        }