Example #1
0
        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));
        }
Example #3
0
        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));
        }