private IEnumerable <T> GetAggregateEnumerable() { // Used to pick the right element from each sub query in the right order var comparer = new OrderingComparer <T>(Expression); // Create lazy queues over each sub query so we can lazily pull items from it var lazyQueues = _subQueries.Select(query => new LazyQueue <T>(query.GetEnumerator())).ToList(); // Used to keep track of everything we've seen so far (we never show duplicates) var seen = new HashSet <T>(_equalityComparer); do { T minElement = default(T); LazyQueue <T> minQueue = null; // Run tasks in parallel var tasks = (from queue in lazyQueues select Task.Factory.StartNew(() => { T current; return(new { Empty = !queue.TryPeek(out current), Value = current, Queue = queue, }); })).ToArray(); // Wait for everything to complete Task.WaitAll(tasks); foreach (var task in tasks) { if (!task.Result.Empty) { // Keep track of the minimum element in the list if (minElement == null || comparer.Compare(task.Result.Value, minElement) < 0) { minElement = task.Result.Value; minQueue = task.Result.Queue; } } else { // Remove the enumerator if it's empty lazyQueues.Remove(task.Result.Queue); } } if (lazyQueues.Any()) { if (seen.Add(minElement)) { yield return(minElement); } // Clear the top of the enumerator we just peeked minQueue.Dequeue(); } } while (lazyQueues.Any()); }
private IEnumerable <TVal> GetAggregateEnumerable() { // Used to pick the right element from each sub query in the right order var comparer = new OrderingComparer <TVal>(Expression); if (!comparer.CanCompare) { // If the original queries do not have sort expressions, we'll use the order of the subqueries to read results out. return(_subQueries.SelectMany(query => _ignoreFailures ? query.SafeIterate() : query) .Distinct(_equalityComparer)); } return(ReadOrderedQueues(comparer)); }
private IEnumerable <TVal> GetAggregateEnumerable() { OrderingComparer <TVal> comparer = new OrderingComparer <TVal>(this.Expression); return(comparer.CanCompare ? this.ReadOrderedQueues(comparer) : (from query in this._subQueries select base._ignoreFailures ? query.SafeIterate <TVal>() : query).Distinct <TVal>(this._equalityComparer)); }