예제 #1
0
        public void GetPostingsTest_OrQueryExist_ReturnsPostings()
        {
            //Some postings overlap
            OrQuery orQuery1 = new OrQuery(new List <IQueryComponent> {
                new TermLiteral("snow"),
                new TermLiteral("mystery")
            });
            IList <Posting> result = orQuery1.GetPostings(index, processor);

            result.Should().HaveCount(5, "because there are 5 files that contain 'snow' or 'mystery'");
            Console.Write(orQuery1.ToString() + "\t");
            PrintPostingResult(result);

            //All postings overlaps
            OrQuery orQuery2 = new OrQuery(new List <IQueryComponent> {
                new TermLiteral("full"),
                new TermLiteral("of")
            });

            result = orQuery2.GetPostings(index, processor);
            result.Should().HaveCount(2, "because there are 2 files that contain 'full' or 'of'");
            Console.Write(orQuery2.ToString() + "\t");
            PrintPostingResult(result);

            //One component returns empty posting list
            OrQuery orQuery3 = new OrQuery(new List <IQueryComponent> {
                new TermLiteral("full"),
                new TermLiteral("zebra")        //no posting for this
            });

            result = orQuery3.GetPostings(index, processor);
            result.Should().HaveCount(2, "because there are 2 files with 'full' and no file with 'zebra'");
            Console.Write(orQuery3.ToString() + "\t");
            PrintPostingResult(result);
        }
예제 #2
0
        public void GetPostingsTest_OrQueryNotExist_ReturnsEmpty()
        {
            OrQuery orQuery = new OrQuery(new List <IQueryComponent> {
                new TermLiteral("running"),
                new TermLiteral("zebra")
            });
            IList <Posting> result = orQuery.GetPostings(index, processor);

            result.Should().BeEmpty("because there is no file with 'running' or 'zebra'");
            Console.Write(orQuery.ToString() + "\t");
            PrintPostingResult(result);
        }
예제 #3
0
        private IList <PackedObject> InternalProcessQuery(OrQuery query)
        {
            var executionPlan = new ExecutionPlan();

            try
            {
                executionPlan.Begin();

                // an empty query should return everything
                if (query.IsEmpty())
                {
                    var all = _dataStore.PrimaryIndex.GetAll().ToList();


                    if (query.OrderByProperty != null)
                    {
                        return(OrderBy(all.ToHashSet(), query.OrderByProperty, query.OrderByIsDescending, executionPlan));
                    }


                    return(all);
                }

                // simplified processing if it is an atomic query
                var atomicQuery = AsAtomic(query);

                if (atomicQuery != null)
                {
                    var res = ProcessSimpleQuery(atomicQuery, executionPlan);


                    if (query.OrderByProperty != null)
                    {
                        return(OrderBy(res.ToHashSet(), query.OrderByProperty, query.OrderByIsDescending, executionPlan));
                    }
                    else
                    {
                        return(res);
                    }
                }


                // if only one AndQuery, process sequentially
                if (query.Elements.Count == 1)
                {
                    var andQuery = query.Elements[0];

                    var set = ProcessAndQuery(andQuery, executionPlan);

                    if (query.OrderByProperty != null)
                    {
                        return(OrderBy(set.ToHashSet(), query.OrderByProperty, query.OrderByIsDescending, executionPlan));
                    }

                    return(set.ToList());
                }

                // if multiple AndQueries run in parallel
                HashSet <PackedObject> orResult = null;

                var results = new IList <PackedObject> [query.Elements.Count];

                Parallel.For(0, query.Elements.Count, i =>
                {
                    var andQuery = query.Elements[i];
                    results[i]   = ProcessAndQuery(andQuery, executionPlan);
                });

                executionPlan.BeginMerge();

                // merge the results (they may contain duplicates)
                foreach (var result in results)
                {
                    if (orResult == null)
                    {
                        orResult = new HashSet <PackedObject>(result);
                    }
                    else
                    {
                        orResult.UnionWith(result);
                    }
                }

                executionPlan.EndMerge();

                if (query.OrderByProperty != null)
                {
                    return(OrderBy(orResult, query.OrderByProperty, query.OrderByIsDescending, executionPlan));
                }


                return(orResult !.ToList());
            }
            finally
            {
                executionPlan.End();
                ExecutionPlan = executionPlan;

                _log?.LogActivity("QUERY", query.CollectionName, executionPlan.TotalTimeInMicroseconds, query.ToString(), query.Description(), executionPlan);
            }
        }