static void Main()
 {
     CounterWrapper c = new CounterWrapper(new Counter());
     CountEventHandler a = n => Console.WriteLine("Alerta " + n);
     c.CountEvent += a; // call add_CountEvent
     c.DoIt(5, 7);
     c.CountEvent -= a; // call remove_CountEvent
     c.DoIt(5, 7);
 }
Exemple #2
0
        internal QueryResult Query(QueryInfo info, CLR.HashSet <string> tagsToExclude = null)
        {
            var timer = Stopwatch.StartNew();
            TagByQueryLookup queryInfo = GetTagByQueryLookup(info.Type);

            ThrowIfInvalidParameters(info.Tag, info.PageSize, queryInfo);
            ThrowIfInvalidParameters(info.OtherTag, info.PageSize, queryInfo);

            var tagCounter              = 0;
            var otherTagCounter         = 0;
            var exclusionCounter        = new CounterWrapper(initialValue: 0);
            IEnumerable <int> tag1Query = queryInfo[info.Tag].Select(t => { tagCounter++; return(t); });
            IEnumerable <int> tag2Query = queryInfo[info.OtherTag].Select(t => { otherTagCounter++; return(t); });
            IEnumerable <int> query     = Enumerable.Empty <int>();

            switch (info.Operator)
            {
            case "AND":
                query = tag1Query.Intersect(tag2Query);
                if (tagsToExclude != null)
                {
                    query = AddExclusionsToQuery(query, tagsToExclude, exclusionCounter);
                }
                break;

            case "AND-NOT":
                query = tag1Query.Except(tag2Query);
                if (tagsToExclude != null)
                {
                    query = AddExclusionsToQuery(query, tagsToExclude, exclusionCounter);
                }
                break;

            case "OR":
                // TODO this has a small bug, we can get items out of order as we pull them thru in pairs
                // if t2 has several items that are larger than t1, t1 will still come out first!!
                // So algorithm needs to be:
                //  1) pull the LARGEST value (from t1 or t2)
                //  2) process this item
                //  3) repeat 1) again
                query = tag1Query.Zip(tag2Query, (t1, t2) => new[] { t1, t2 })
                        .SelectMany(item => item)
                        .Distinct();
                if (tagsToExclude != null)
                {
                    query = AddExclusionsToQuery(query, tagsToExclude, exclusionCounter);
                }
                break;

            case "OR-NOT":     //"i.e. .net+or+jquery-"
                // TODO this has a small bug, we can get items out of order as we pull them thru in pairs
                // if t2 has several items that are larger than t1, t1 will still come out first!!
                // So algorithm needs to be:
                //  1) pull the LARGEST value (from t1 or t2)
                //  2) process this item
                //  3) repeat 1) again
                query = tag1Query.Zip(queryInfo[TagServer.ALL_TAGS_KEY], (t1, t2) => new[] { t1, t2 })
                        .SelectMany(item => item)
                        .Except(tag2Query)
                        .Distinct();
                if (tagsToExclude != null)
                {
                    query = AddExclusionsToQuery(query, tagsToExclude, exclusionCounter);
                }
                break;

            // TODO Work out what a "NOT" query really means, at the moment it's the same as "AND-NOT"?!
            //case "NOT":
            //    query = tag1Query.Except(tag2Query);
            //    if (tagsToExclude != null)
            //        query = AddExclusionsToQuery(query, tagsToExclude, exclusionCounter);
            //    break;

            default:
                throw new InvalidOperationException(string.Format("Invalid operator specified: {0}", info.Operator ?? "<NULL>"));
            }

            var results = query.Skip(info.Skip)
                          .Take(info.PageSize)
                          .Select(i => questions[i])
                          .ToList();

            timer.Stop();

            Results.AddData(timer.Elapsed.TotalMilliseconds.ToString("#.##"));

            Logger.Log("REGULAR  Boolean Query: \"{0}\" {1} \"{2}\", pageSize = {3:N0}, skip = {4:N0}, took {5} ({6:N2} ms) REGULAR",
                       info.Tag, info.Operator, info.OtherTag, info.PageSize, info.Skip, timer.Elapsed, timer.Elapsed.TotalMilliseconds);
            Logger.Log("Got {0:} results in total, tag1 QueryCounter = {1:N0}, tag2 QueryCounter = {1:N0}",
                       results.Count(), tagCounter, otherTagCounter);

            //PrintResults(results, string.Format("{0} {1} {2}", info.Tag, info.Operator, info.OtherTag), info.Type);

            return(new QueryResult
            {
                Questions = results,
                Counters = new Dictionary <string, int>
                {
                    { "TagCounter", tagCounter },
                    { "OtherTagCounter", otherTagCounter },
                    { "ExclusionCounter", exclusionCounter.Counter }
                }
            });
        }
 public SubscriberWrapper(CounterWrapper c)
 {
     this.c = c;
 }
Exemple #4
0
 private IEnumerable <int> AddExclusionsToQuery(IEnumerable <int> query, CLR.HashSet <string> tagsToExclude, CounterWrapper exclusionCounter)
 {
     return(query.Where(i =>
     {
         if (questions[i].Tags.All(t => tagsToExclude.Contains(t) == false))
         {
             return true;
         }
         exclusionCounter.Counter++;
         return false;
     }));
 }