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