//---------------------------------------------------------------------------------------
            // Tallies up the min/max of the underlying data source, walking the entire thing the first
            // time MoveNext is called on this object.
            //

            protected override bool MoveNextCore(ref int currentElement)
            {
                // Based on the sign, do either a min or max reduction.
                QueryOperatorEnumerator <int, TKey> source = m_source;
                TKey keyUnused = default(TKey);

                if (source.MoveNext(ref currentElement, ref keyUnused))
                {
                    int i = 0;
                    // We just scroll through the enumerator and find the min or max.
                    if (m_sign == -1)
                    {
                        int elem = default(int);
                        while (source.MoveNext(ref elem, ref keyUnused))
                        {
                            if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                            {
                                CancellationState.ThrowIfCanceled(m_cancellationToken);
                            }

                            if (elem < currentElement)
                            {
                                currentElement = elem;
                            }
                        }
                    }
                    else
                    {
                        int elem = default(int);
                        while (source.MoveNext(ref elem, ref keyUnused))
                        {
                            if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                            {
                                CancellationState.ThrowIfCanceled(m_cancellationToken);
                            }

                            if (elem > currentElement)
                            {
                                currentElement = elem;
                            }
                        }
                    }

                    // The sum has been calculated. Now just return.
                    return(true);
                }

                return(false);
            }
예제 #2
0
        //-----------------------------------------------------------------------------------
        // Builds the hash lookup, transforming from TSource to TElement through whatever means is appropriate.
        //

        protected override HashLookup <Wrapper <TGroupKey>, GroupKeyData> BuildHashLookup()
        {
            HashLookup <Wrapper <TGroupKey>, GroupKeyData> hashLookup = new HashLookup <Wrapper <TGroupKey>, GroupKeyData>(
                new WrapperEqualityComparer <TGroupKey>(_keyComparer));

            Pair <TSource, TGroupKey> sourceElement = default(Pair <TSource, TGroupKey>);
            TOrderKey sourceOrderKey = default(TOrderKey);
            int       i = 0;

            while (_source.MoveNext(ref sourceElement, ref sourceOrderKey))
            {
                if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                {
                    CancellationState.ThrowIfCanceled(_cancellationToken);
                }

                // Generate a key and place it into the hashtable.
                Wrapper <TGroupKey> key = new Wrapper <TGroupKey>(sourceElement.Second);

                // If the key already exists, we just append it to the existing list --
                // otherwise we will create a new one and add it to that instead.
                GroupKeyData currentValue = null;
                if (hashLookup.TryGetValue(key, ref currentValue))
                {
                    if (_orderComparer.Compare(sourceOrderKey, currentValue._orderKey) < 0)
                    {
                        currentValue._orderKey = sourceOrderKey;
                    }
                }
                else
                {
                    currentValue = new GroupKeyData(sourceOrderKey, key.Value, _orderComparer);

                    hashLookup.Add(key, currentValue);
                }

                Debug.Assert(currentValue != null);

                currentValue._grouping.Add(sourceElement.First, sourceOrderKey);
            }

            // Sort the elements within each group
            for (int j = 0; j < hashLookup.Count; j++)
            {
                hashLookup[j].Value._grouping.DoneAdding();
            }

            return(hashLookup);
        }
 internal override bool MoveNext(ref TInputOutput currentElement, ref int currentKey)
 {
     if (this.m_hashLookup == null)
     {
         this.m_hashLookup      = new System.Linq.Parallel.Set <TInputOutput>(this.m_comparer);
         this.m_outputLoopCount = new Shared <int>(0);
     }
     if (this.m_leftSource != null)
     {
         TLeftKey local = default(TLeftKey);
         Pair <TInputOutput, NoKeyMemoizationRequired> pair = new Pair <TInputOutput, NoKeyMemoizationRequired>();
         int num = 0;
         while (this.m_leftSource.MoveNext(ref pair, ref local))
         {
             if ((num++ & 0x3f) == 0)
             {
                 CancellationState.ThrowIfCanceled(this.m_cancellationToken);
             }
             if (this.m_hashLookup.Add(pair.First))
             {
                 currentElement = pair.First;
                 return(true);
             }
         }
         this.m_leftSource.Dispose();
         this.m_leftSource = null;
     }
     if (this.m_rightSource != null)
     {
         TRightKey local2 = default(TRightKey);
         Pair <TInputOutput, NoKeyMemoizationRequired> pair2 = new Pair <TInputOutput, NoKeyMemoizationRequired>();
         while (this.m_rightSource.MoveNext(ref pair2, ref local2))
         {
             if ((this.m_outputLoopCount.Value++ & 0x3f) == 0)
             {
                 CancellationState.ThrowIfCanceled(this.m_cancellationToken);
             }
             if (this.m_hashLookup.Add(pair2.First))
             {
                 currentElement = pair2.First;
                 return(true);
             }
         }
         this.m_rightSource.Dispose();
         this.m_rightSource = null;
     }
     return(false);
 }
예제 #4
0
        private void EnumerateAndRedistributeElements()
        {
            Mutables <TInputOutput, THashKey, TOrderKey> mutables = this.m_mutables;

            ListChunk <Pair <TInputOutput, THashKey> >[] chunkArray = new ListChunk <Pair <TInputOutput, THashKey> > [this.m_partitionCount];
            ListChunk <TOrderKey>[] chunkArray2    = new ListChunk <TOrderKey> [this.m_partitionCount];
            TInputOutput            currentElement = default(TInputOutput);
            TOrderKey currentKey = default(TOrderKey);
            int       num        = 0;

            while (this.m_source.MoveNext(ref currentElement, ref currentKey))
            {
                int num2;
                if ((num++ & 0x3f) == 0)
                {
                    CancellationState.ThrowIfCanceled(this.m_cancellationToken);
                }
                THashKey key = default(THashKey);
                if (this.m_keySelector != null)
                {
                    key  = this.m_keySelector(currentElement);
                    num2 = this.m_repartitionStream.GetHashCode(key) % this.m_partitionCount;
                }
                else
                {
                    num2 = this.m_repartitionStream.GetHashCode(currentElement) % this.m_partitionCount;
                }
                ListChunk <Pair <TInputOutput, THashKey> > chunk = chunkArray[num2];
                ListChunk <TOrderKey> chunk2 = chunkArray2[num2];
                if (chunk == null)
                {
                    chunkArray[num2]  = chunk = new ListChunk <Pair <TInputOutput, THashKey> >(0x80);
                    chunkArray2[num2] = chunk2 = new ListChunk <TOrderKey>(0x80);
                }
                chunk.Add(new Pair <TInputOutput, THashKey>(currentElement, key));
                chunk2.Add(currentKey);
            }
            for (int i = 0; i < this.m_partitionCount; i++)
            {
                this.m_valueExchangeMatrix[this.m_partitionIndex, i] = chunkArray[i];
                this.m_keyExchangeMatrix[this.m_partitionIndex, i]   = chunkArray2[i];
            }
            this.m_barrier.Signal();
            mutables.m_currentBufferIndex = this.m_partitionIndex;
            mutables.m_currentBuffer      = chunkArray[this.m_partitionIndex];
            mutables.m_currentKeyBuffer   = chunkArray2[this.m_partitionIndex];
            mutables.m_currentIndex       = -1;
        }
예제 #5
0
            internal override bool MoveNext(ref TInput currentElement, ref int currentKey)
            {
                TInput local  = default(TInput);
                TKey   local2 = default(TKey);
                int    num    = 0;

                while (this.m_source.MoveNext(ref local, ref local2))
                {
                    if ((num++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(this.m_cancellationToken);
                    }
                    this.m_elementAction(local);
                }
                return(false);
            }
예제 #6
0
            //---------------------------------------------------------------------------------------
            // Walks the single data source, skipping elements it has already seen.
            //

            internal override bool MoveNext(ref TInputOutput currentElement, ref TKey currentKey)
            {
                Debug.Assert(_source != null);
                Debug.Assert(_hashLookup != null);

                if (_hashLookupEnumerator == null)
                {
                    Pair <TInputOutput, NoKeyMemoizationRequired> elem = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                    TKey orderKey = default(TKey);

                    int i = 0;
                    while (_source.MoveNext(ref elem, ref orderKey))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        // For each element, we track the smallest order key for that element that we saw so far
                        TKey oldEntry;

                        Wrapper <TInputOutput> wrappedElem = new Wrapper <TInputOutput>(elem.First);

                        // If this is the first occurrence of this element, or the order key is lower than all keys we saw previously,
                        // update the order key for this element.
                        if (!_hashLookup.TryGetValue(wrappedElem, out oldEntry) || _keyComparer.Compare(orderKey, oldEntry) < 0)
                        {
                            // For each "elem" value, we store the smallest key, and the element value that had that key.
                            // Note that even though two element values are "equal" according to the EqualityComparer,
                            // we still cannot choose arbitrarily which of the two to yield.
                            _hashLookup[wrappedElem] = orderKey;
                        }
                    }

                    _hashLookupEnumerator = _hashLookup.GetEnumerator();
                }

                if (_hashLookupEnumerator.MoveNext())
                {
                    KeyValuePair <Wrapper <TInputOutput>, TKey> currentPair = _hashLookupEnumerator.Current;
                    currentElement = currentPair.Key.Value;
                    currentKey     = currentPair.Value;
                    return(true);
                }

                return(false);
            }
예제 #7
0
        protected void BuildBaseHashLookup <TBaseBuilder, TBaseElement, TBaseOrderKey>(
            QueryOperatorEnumerator <Pair <TBaseElement, THashKey>, TBaseOrderKey> dataSource,
            TBaseBuilder baseHashBuilder,
            CancellationToken cancellationToken) where TBaseBuilder : IBaseHashBuilder <TBaseElement, TBaseOrderKey>
        {
            Debug.Assert(dataSource != null);

#if DEBUG
            int hashLookupCount   = 0;
            int hashKeyCollisions = 0;
#endif

            Pair <TBaseElement, THashKey> currentPair = default(Pair <TBaseElement, THashKey>);
            TBaseOrderKey orderKey = default(TBaseOrderKey);
            int           i        = 0;
            while (dataSource.MoveNext(ref currentPair, ref orderKey))
            {
                if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                {
                    CancellationState.ThrowIfCanceled(cancellationToken);
                }

                TBaseElement element = currentPair.First;
                THashKey     hashKey = currentPair.Second;

                // We ignore null keys.
                if (hashKey != null)
                {
#if DEBUG
                    hashLookupCount++;
#endif

                    if (baseHashBuilder.Add(hashKey, element, orderKey))
                    {
#if DEBUG
                        hashKeyCollisions++;
#endif
                    }
                }
            }

#if DEBUG
            TraceHelpers.TraceInfo("HashLookupBuilder::BuildBaseHashLookup - built hash table [count = {0}, collisions = {1}]",
                                   hashLookupCount, hashKeyCollisions);
#endif
        }
 internal override bool MoveNext(ref TInputOutput currentElement, ref TLeftKey currentKey)
 {
     if (this.m_outputEnumerator == null)
     {
         System.Linq.Parallel.Set <TInputOutput>       set  = new System.Linq.Parallel.Set <TInputOutput>(this.m_comparer);
         Pair <TInputOutput, NoKeyMemoizationRequired> pair = new Pair <TInputOutput, NoKeyMemoizationRequired>();
         int num  = 0;
         int num2 = 0;
         while (this.m_rightSource.MoveNext(ref pair, ref num))
         {
             if ((num2++ & 0x3f) == 0)
             {
                 CancellationState.ThrowIfCanceled(this.m_cancellationToken);
             }
             set.Add(pair.First);
         }
         Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, TLeftKey> > dictionary = new Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, TLeftKey> >(new WrapperEqualityComparer <TInputOutput>(this.m_comparer));
         Pair <TInputOutput, NoKeyMemoizationRequired> pair2 = new Pair <TInputOutput, NoKeyMemoizationRequired>();
         TLeftKey local = default(TLeftKey);
         while (this.m_leftSource.MoveNext(ref pair2, ref local))
         {
             if ((num2++ & 0x3f) == 0)
             {
                 CancellationState.ThrowIfCanceled(this.m_cancellationToken);
             }
             if (!set.Contains(pair2.First))
             {
                 Pair <TInputOutput, TLeftKey> pair3;
                 Wrapper <TInputOutput>        key = new Wrapper <TInputOutput>(pair2.First);
                 if (!dictionary.TryGetValue(key, out pair3) || (this.m_leftKeyComparer.Compare(local, pair3.Second) < 0))
                 {
                     dictionary[key] = new Pair <TInputOutput, TLeftKey>(pair2.First, local);
                 }
             }
         }
         this.m_outputEnumerator = dictionary.GetEnumerator();
     }
     if (this.m_outputEnumerator.MoveNext())
     {
         Pair <TInputOutput, TLeftKey> pair4 = this.m_outputEnumerator.Current.Value;
         currentElement = pair4.First;
         currentKey     = pair4.Second;
         return(true);
     }
     return(false);
 }
예제 #9
0
            internal override bool MoveNext(ref TInputOutput currentElement, ref TLeftKey currentKey)
            {
                int num = 0;

                if (this.m_hashLookup == null)
                {
                    this.m_hashLookup = new Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, TLeftKey> >(this.m_comparer);
                    Pair <TInputOutput, NoKeyMemoizationRequired> pair = new Pair <TInputOutput, NoKeyMemoizationRequired>();
                    TLeftKey local = default(TLeftKey);
                    while (this.m_leftSource.MoveNext(ref pair, ref local))
                    {
                        Pair <TInputOutput, TLeftKey> pair2;
                        if ((num++ & 0x3f) == 0)
                        {
                            CancellationState.ThrowIfCanceled(this.m_cancellationToken);
                        }
                        Wrapper <TInputOutput> key = new Wrapper <TInputOutput>(pair.First);
                        if (!this.m_hashLookup.TryGetValue(key, out pair2) || (this.m_leftKeyComparer.Compare(local, pair2.Second) < 0))
                        {
                            this.m_hashLookup[key] = new Pair <TInputOutput, TLeftKey>(pair.First, local);
                        }
                    }
                }
                Pair <TInputOutput, NoKeyMemoizationRequired> pair3 = new Pair <TInputOutput, NoKeyMemoizationRequired>();
                int num2 = 0;

                while (this.m_rightSource.MoveNext(ref pair3, ref num2))
                {
                    Pair <TInputOutput, TLeftKey> pair4;
                    if ((num++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(this.m_cancellationToken);
                    }
                    Wrapper <TInputOutput> wrapper2 = new Wrapper <TInputOutput>(pair3.First);
                    if (this.m_hashLookup.TryGetValue(wrapper2, out pair4))
                    {
                        currentElement = pair4.First;
                        currentKey     = pair4.Second;
                        this.m_hashLookup.Remove(new Wrapper <TInputOutput>(pair4.First));
                        return(true);
                    }
                }
                return(false);
            }
 internal override bool MoveNext(ref TInputOutput currentElement, ref TKey currentKey)
 {
     if (this.m_outputLoopCount == null)
     {
         this.m_outputLoopCount = new Shared <int>(0);
     }
     while (this.m_source.MoveNext(ref currentElement, ref currentKey))
     {
         if ((this.m_outputLoopCount.Value++ & 0x3f) == 0)
         {
             CancellationState.ThrowIfCanceled(this.m_cancellationToken);
         }
         if (this.m_predicate(currentElement))
         {
             return(true);
         }
     }
     return(false);
 }
 internal override bool MoveNext(ref TIntermediate currentElement, ref int currentKey)
 {
     if (!this.m_accumulated)
     {
         this.m_accumulated = true;
         bool          flag  = false;
         TIntermediate local = default(TIntermediate);
         if (this.m_reduceOperator.m_seedIsSpecified)
         {
             local = (this.m_reduceOperator.m_seedFactory == null) ? this.m_reduceOperator.m_seed : this.m_reduceOperator.m_seedFactory();
         }
         else
         {
             TInput local2 = default(TInput);
             TKey   local3 = default(TKey);
             if (!this.m_source.MoveNext(ref local2, ref local3))
             {
                 return(false);
             }
             flag  = true;
             local = (TIntermediate)local2;
         }
         TInput local4 = default(TInput);
         TKey   local5 = default(TKey);
         int    num    = 0;
         while (this.m_source.MoveNext(ref local4, ref local5))
         {
             if ((num++ & 0x3f) == 0)
             {
                 CancellationState.ThrowIfCanceled(this.m_cancellationToken);
             }
             flag  = true;
             local = this.m_reduceOperator.m_intermediateReduce(local, local4);
         }
         if (flag)
         {
             currentElement = local;
             currentKey     = this.m_partitionIndex;
             return(true);
         }
     }
     return(false);
 }
            protected override bool MoveNextCore(ref float currentElement)
            {
                QueryOperatorEnumerator <float, TKey> source = this.m_source;
                TKey currentKey = default(TKey);

                if (!source.MoveNext(ref currentElement, ref currentKey))
                {
                    return(false);
                }
                int num = 0;

                if (this.m_sign == -1)
                {
                    float num2 = 0f;
                    while (source.MoveNext(ref num2, ref currentKey))
                    {
                        if ((num++ & 0x3f) == 0)
                        {
                            CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                        }
                        if ((num2 < currentElement) || float.IsNaN(num2))
                        {
                            currentElement = num2;
                        }
                    }
                }
                else
                {
                    float num3 = 0f;
                    while (source.MoveNext(ref num3, ref currentKey))
                    {
                        if ((num++ & 0x3f) == 0)
                        {
                            CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                        }
                        if ((num3 > currentElement) || float.IsNaN(currentElement))
                        {
                            currentElement = num3;
                        }
                    }
                }
                return(true);
            }
예제 #13
0
 internal override bool MoveNext(ref TOutput currentElement, ref Pair <TLeftKey, int> currentKey)
 {
     while (true)
     {
         if (this.m_currentRightSource == null)
         {
             this.m_mutables = new Mutables <TLeftInput, TRightInput, TOutput, TLeftKey>();
             if ((this.m_mutables.m_lhsCount++ & 0x3f) == 0)
             {
                 CancellationState.ThrowIfCanceled(this.m_cancellationToken);
             }
             if (!this.m_leftSource.MoveNext(ref this.m_mutables.m_currentLeftElement, ref this.m_mutables.m_currentLeftKey))
             {
                 return(false);
             }
             this.m_currentRightSource = this.m_selectManyOperator.m_rightChildSelector(this.m_mutables.m_currentLeftElement).GetEnumerator();
             if (this.m_selectManyOperator.m_resultSelector == null)
             {
                 this.m_currentRightSourceAsOutput = (IEnumerator <TOutput>) this.m_currentRightSource;
             }
         }
         if (this.m_currentRightSource.MoveNext())
         {
             this.m_mutables.m_currentRightSourceIndex++;
             if (this.m_selectManyOperator.m_resultSelector != null)
             {
                 currentElement = this.m_selectManyOperator.m_resultSelector(this.m_mutables.m_currentLeftElement, this.m_currentRightSource.Current);
             }
             else
             {
                 currentElement = this.m_currentRightSourceAsOutput.Current;
             }
             currentKey = new Pair <TLeftKey, int>(this.m_mutables.m_currentLeftKey, this.m_mutables.m_currentRightSourceIndex);
             return(true);
         }
         this.m_currentRightSource.Dispose();
         this.m_currentRightSource         = null;
         this.m_currentRightSourceAsOutput = null;
     }
 }
예제 #14
0
            internal override bool MoveNext(ref TSource currentElement, ref int currentKey)
            {
                int num = 0;

                while (this.m_source.MoveNext(ref currentElement, ref currentKey))
                {
                    if ((num++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(this.m_cancellationToken);
                    }
                    if (this.m_resultFoundFlag.Value)
                    {
                        break;
                    }
                    if (currentKey == this.m_index)
                    {
                        this.m_resultFoundFlag.Value = true;
                        return(true);
                    }
                }
                return(false);
            }
            internal override bool MoveNext(ref TInputOutput currentElement, ref int currentKey)
            {
                TKey local = default(TKey);
                Pair <TInputOutput, NoKeyMemoizationRequired> pair = new Pair <TInputOutput, NoKeyMemoizationRequired>();

                if (this.m_outputLoopCount == null)
                {
                    this.m_outputLoopCount = new Shared <int>(0);
                }
                while (this.m_source.MoveNext(ref pair, ref local))
                {
                    if ((this.m_outputLoopCount.Value++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(this.m_cancellationToken);
                    }
                    if (this.m_hashLookup.Add(pair.First))
                    {
                        currentElement = pair.First;
                        return(true);
                    }
                }
                return(false);
            }
예제 #16
0
        protected override HashLookup <Wrapper <TGroupKey>, OrderedGroupByQueryOperatorEnumerator <TSource, TGroupKey, TSource, TOrderKey> .GroupKeyData> BuildHashLookup()
        {
            HashLookup <Wrapper <TGroupKey>, OrderedGroupByQueryOperatorEnumerator <TSource, TGroupKey, TSource, TOrderKey> .GroupKeyData> lookup = new HashLookup <Wrapper <TGroupKey>, OrderedGroupByQueryOperatorEnumerator <TSource, TGroupKey, TSource, TOrderKey> .GroupKeyData>(new WrapperEqualityComparer <TGroupKey>(base.m_keyComparer));
            Pair <TSource, TGroupKey> currentElement = new Pair <TSource, TGroupKey>();
            TOrderKey currentKey = default(TOrderKey);
            int       num        = 0;

            while (base.m_source.MoveNext(ref currentElement, ref currentKey))
            {
                if ((num++ & 0x3f) == 0)
                {
                    CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                }
                Wrapper <TGroupKey> key = new Wrapper <TGroupKey>(currentElement.Second);
                OrderedGroupByQueryOperatorEnumerator <TSource, TGroupKey, TSource, TOrderKey> .GroupKeyData data = null;
                if (lookup.TryGetValue(key, ref data))
                {
                    if (base.m_orderComparer.Compare(currentKey, data.m_orderKey) < 0)
                    {
                        data.m_orderKey = currentKey;
                    }
                }
                else
                {
                    data = new OrderedGroupByQueryOperatorEnumerator <TSource, TGroupKey, TSource, TOrderKey> .GroupKeyData(currentKey, key.Value, base.m_orderComparer);

                    lookup.Add(key, data);
                }
                data.m_grouping.Add(currentElement.First, currentKey);
            }
            for (int i = 0; i < lookup.Count; i++)
            {
                KeyValuePair <Wrapper <TGroupKey>, OrderedGroupByQueryOperatorEnumerator <TSource, TGroupKey, TSource, TOrderKey> .GroupKeyData> pair2 = lookup[i];
                pair2.Value.m_grouping.DoneAdding();
            }
            return(lookup);
        }
            protected override bool MoveNextCore(ref Pair <decimal, long> currentElement)
            {
                decimal first  = 0.0M;
                long    second = 0L;
                QueryOperatorEnumerator <decimal?, TKey> source = this.m_source;
                decimal?nullable   = null;
                TKey    currentKey = default(TKey);
                int     num3       = 0;

                while (source.MoveNext(ref nullable, ref currentKey))
                {
                    if ((num3++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                    }
                    if (nullable.HasValue)
                    {
                        first  += nullable.GetValueOrDefault();
                        second += 1L;
                    }
                }
                currentElement = new Pair <decimal, long>(first, second);
                return(second > 0L);
            }
예제 #18
0
            //---------------------------------------------------------------------------------------
            // Walks the two data sources, left and then right, to produce the union.
            //

            internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInputOutput currentElement, ref ConcatKey <TLeftKey, TRightKey> currentKey)
            {
                Debug.Assert(_leftSource != null);
                Debug.Assert(_rightSource != null);

                if (_outputEnumerator == null)
                {
                    IEqualityComparer <Wrapper <TInputOutput> > wrapperComparer = new WrapperEqualityComparer <TInputOutput>(_comparer);
                    Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > > union =
                        new Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, ConcatKey <TLeftKey, TRightKey> > >(wrapperComparer);

                    Pair <TInputOutput, NoKeyMemoizationRequired> elem = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                    TLeftKey leftKey = default(TLeftKey) !;

                    int i = 0;
                    while (_leftSource.MoveNext(ref elem, ref leftKey))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        ConcatKey <TLeftKey, TRightKey> key =
                            ConcatKey <TLeftKey, TRightKey> .MakeLeft(_leftOrdered?leftKey : default);
예제 #19
0
            //---------------------------------------------------------------------------------------
            // Just walks the entire data source upon its first invocation, performing the per-
            // element action for each element.
            //

            internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref TInput currentElement, ref int currentKey)
            {
                Debug.Assert(_elementAction != null, "expected a compiled operator");

                // We just scroll through the enumerator and execute the action. Because we execute
                // "in place", we actually never even produce a single value.

                // Cancellation testing must be performed here as full enumeration occurs within this method.
                // We only need to throw a simple exception here.. marshalling logic handled via QueryTaskGroupState.QueryEnd (called by ForAllSpoolingTask)
                TInput element   = default(TInput) !;
                TKey   keyUnused = default(TKey) !;
                int    i         = 0;

                while (_source.MoveNext(ref element, ref keyUnused))
                {
                    if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(_cancellationToken);
                    }
                    _elementAction(element);
                }

                return(false);
            }
예제 #20
0
            protected override bool MoveNextCore(ref double currentElement)
            {
                float num        = 0f;
                TKey  currentKey = default(TKey);
                QueryOperatorEnumerator <float, TKey> source = this.m_source;

                if (!source.MoveNext(ref num, ref currentKey))
                {
                    return(false);
                }
                double num2 = 0.0;
                int    num3 = 0;

                do
                {
                    if ((num3++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                    }
                    num2 += num;
                }while (source.MoveNext(ref num, ref currentKey));
                currentElement = num2;
                return(true);
            }
            protected override bool MoveNextCore(ref long currentElement)
            {
                TSource local      = default(TSource);
                TKey    currentKey = default(TKey);
                QueryOperatorEnumerator <TSource, TKey> source = this.m_source;

                if (!source.MoveNext(ref local, ref currentKey))
                {
                    return(false);
                }
                long num  = 0L;
                int  num2 = 0;

                do
                {
                    if ((num2++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                    }
                    num += 1L;
                }while (source.MoveNext(ref local, ref currentKey));
                currentElement = num;
                return(true);
            }
예제 #22
0
        protected override HashLookup <Wrapper <TGroupKey>, ListChunk <TSource> > BuildHashLookup()
        {
            HashLookup <Wrapper <TGroupKey>, ListChunk <TSource> > lookup = new HashLookup <Wrapper <TGroupKey>, ListChunk <TSource> >(new WrapperEqualityComparer <TGroupKey>(base.m_keyComparer));
            Pair <TSource, TGroupKey> currentElement = new Pair <TSource, TGroupKey>();
            TOrderKey currentKey = default(TOrderKey);
            int       num        = 0;

            while (base.m_source.MoveNext(ref currentElement, ref currentKey))
            {
                if ((num++ & 0x3f) == 0)
                {
                    CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                }
                Wrapper <TGroupKey> key   = new Wrapper <TGroupKey>(currentElement.Second);
                ListChunk <TSource> chunk = null;
                if (!lookup.TryGetValue(key, ref chunk))
                {
                    chunk = new ListChunk <TSource>(2);
                    lookup.Add(key, chunk);
                }
                chunk.Add(currentElement.First);
            }
            return(lookup);
        }
            internal override bool MoveNext(ref bool currentElement, ref int currentKey)
            {
                if (this.m_resultFoundFlag.Value)
                {
                    return(false);
                }
                TInput local  = default(TInput);
                TKey   local2 = default(TKey);

                if (!this.m_source.MoveNext(ref local, ref local2))
                {
                    return(false);
                }
                currentElement = false;
                currentKey     = this.m_partitionIndex;
                int num = 0;

                do
                {
                    if ((num++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(this.m_cancellationToken);
                    }
                    if (this.m_resultFoundFlag.Value)
                    {
                        return(false);
                    }
                    if (this.m_comparer.Equals(local, this.m_searchValue))
                    {
                        this.m_resultFoundFlag.Value = true;
                        currentElement = true;
                        break;
                    }
                }while (this.m_source.MoveNext(ref local, ref local2));
                return(true);
            }
            protected override bool MoveNextCore(ref double?currentElement)
            {
                float?nullable   = null;
                TKey  currentKey = default(TKey);
                QueryOperatorEnumerator <float?, TKey> source = this.m_source;

                if (!source.MoveNext(ref nullable, ref currentKey))
                {
                    return(false);
                }
                float num  = 0f;
                int   num2 = 0;

                do
                {
                    if ((num2++ & 0x3f) == 0)
                    {
                        CancellationState.ThrowIfCanceled(base.m_cancellationToken);
                    }
                    num += nullable.GetValueOrDefault();
                }while (source.MoveNext(ref nullable, ref currentKey));
                currentElement = new double?((double)num);
                return(true);
            }
예제 #25
0
        //-----------------------------------------------------------------------------------
        // Builds the hash lookup, transforming from TSource to TElement through whatever means is appropriate.
        //

        protected override HashLookup <Wrapper <TGroupKey>, ListChunk <TElement> > BuildHashLookup()
        {
            HashLookup <Wrapper <TGroupKey>, ListChunk <TElement> > hashlookup =
                new HashLookup <Wrapper <TGroupKey>, ListChunk <TElement> >(new WrapperEqualityComparer <TGroupKey>(_keyComparer));

            Pair <TSource, TGroupKey> sourceElement = default(Pair <TSource, TGroupKey>);
            TOrderKey sourceKeyUnused = default(TOrderKey);
            int       i = 0;

            while (_source.MoveNext(ref sourceElement, ref sourceKeyUnused))
            {
                if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                {
                    CancellationState.ThrowIfCanceled(_cancellationToken);
                }

                // Generate a key and place it into the hashtable.
                Wrapper <TGroupKey> key = new Wrapper <TGroupKey>(sourceElement.Second);

                // If the key already exists, we just append it to the existing list --
                // otherwise we will create a new one and add it to that instead.
                ListChunk <TElement> currentValue = null;
                if (!hashlookup.TryGetValue(key, ref currentValue))
                {
                    const int INITIAL_CHUNK_SIZE = 2;
                    currentValue = new ListChunk <TElement>(INITIAL_CHUNK_SIZE);
                    hashlookup.Add(key, currentValue);
                }
                Debug.Assert(currentValue != null);

                // Call to the base class to yield the current value.
                currentValue.Add(_elementSelector(sourceElement.First));
            }

            return(hashlookup);
        }
예제 #26
0
            //---------------------------------------------------------------------------------------
            // Walks the two data sources, left and then right, to produce the intersection.
            //

            internal override bool MoveNext(ref TInputOutput currentElement, ref TLeftKey currentKey)
            {
                Debug.Assert(_leftSource != null);
                Debug.Assert(_rightSource != null);

                // Build the set out of the left data source, if we haven't already.
                int i = 0;

                if (_hashLookup == null)
                {
                    _hashLookup = new Dictionary <Wrapper <TInputOutput>, Pair <TInputOutput, TLeftKey> >(_comparer);

                    Pair <TInputOutput, NoKeyMemoizationRequired> leftElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                    TLeftKey leftKey = default(TLeftKey);
                    while (_leftSource.MoveNext(ref leftElement, ref leftKey))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        // For each element, we track the smallest order key for that element that we saw so far
                        Pair <TInputOutput, TLeftKey> oldEntry;
                        Wrapper <TInputOutput>        wrappedLeftElem = new Wrapper <TInputOutput>(leftElement.First);

                        // If this is the first occurrence of this element, or the order key is lower than all keys we saw previously,
                        // update the order key for this element.
                        if (!_hashLookup.TryGetValue(wrappedLeftElem, out oldEntry) || _leftKeyComparer.Compare(leftKey, oldEntry.Second) < 0)
                        {
                            // For each "elem" value, we store the smallest key, and the element value that had that key.
                            // Note that even though two element values are "equal" according to the EqualityComparer,
                            // we still cannot choose arbitrarily which of the two to yield.
                            _hashLookup[wrappedLeftElem] = new Pair <TInputOutput, TLeftKey>(leftElement.First, leftKey);
                        }
                    }
                }

                // Now iterate over the right data source, looking for matches.
                Pair <TInputOutput, NoKeyMemoizationRequired> rightElement = default(Pair <TInputOutput, NoKeyMemoizationRequired>);
                int rightKeyUnused = default(int);

                while (_rightSource.MoveNext(ref rightElement, ref rightKeyUnused))
                {
                    if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(_cancellationToken);
                    }

                    // If we found the element in our set, and if we haven't returned it yet,
                    // we can yield it to the caller. We also mark it so we know we've returned
                    // it once already and never will again.

                    Pair <TInputOutput, TLeftKey> entry;
                    Wrapper <TInputOutput>        wrappedRightElem = new Wrapper <TInputOutput>(rightElement.First);

                    if (_hashLookup.TryGetValue(wrappedRightElem, out entry))
                    {
                        currentElement = entry.First;
                        currentKey     = entry.Second;

                        _hashLookup.Remove(new Wrapper <TInputOutput>(entry.First));
                        return(true);
                    }
                }

                return(false);
            }
예제 #27
0
            //---------------------------------------------------------------------------------------
            // Walks the two data sources, left and then right, to produce the distinct set
            //

            internal override bool MoveNext(ref TInputOutput currentElement, ref TLeftKey currentKey)
            {
                Contract.Assert(_leftSource != null);
                Contract.Assert(_rightSource != null);

                // Build the set out of the left data source, if we haven't already.
                if (_outputEnumerator == null)
                {
                    Set <TInputOutput> rightLookup = new Set <TInputOutput>(_comparer);

                    Pair rightElement   = new Pair(default(TInputOutput), default(NoKeyMemoizationRequired));
                    int  rightKeyUnused = default(int);
                    int  i = 0;
                    while (_rightSource.MoveNext(ref rightElement, ref rightKeyUnused))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        rightLookup.Add((TInputOutput)rightElement.First);
                    }

                    var leftLookup =
                        new Dictionary <Wrapper <TInputOutput>, Pair>(
                            new WrapperEqualityComparer <TInputOutput>(_comparer));

                    Pair     leftElement = new Pair(default(TInputOutput), default(NoKeyMemoizationRequired));
                    TLeftKey leftKey     = default(TLeftKey);
                    while (_leftSource.MoveNext(ref leftElement, ref leftKey))
                    {
                        if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        if (rightLookup.Contains((TInputOutput)leftElement.First))
                        {
                            continue;
                        }

                        Pair oldEntry;
                        Wrapper <TInputOutput> wrappedLeftElement = new Wrapper <TInputOutput>((TInputOutput)leftElement.First);
                        if (!leftLookup.TryGetValue(wrappedLeftElement, out oldEntry) || _leftKeyComparer.Compare(leftKey, (TLeftKey)oldEntry.Second) < 0)
                        {
                            // For each "elem" value, we store the smallest key, and the element value that had that key.
                            // Note that even though two element values are "equal" according to the EqualityComparer,
                            // we still cannot choose arbitrarily which of the two to yield.
                            leftLookup[wrappedLeftElement] = new Pair(leftElement.First, leftKey);
                        }
                    }

                    _outputEnumerator = leftLookup.GetEnumerator();
                }

                if (_outputEnumerator.MoveNext())
                {
                    Pair currentPair = _outputEnumerator.Current.Value;
                    currentElement = (TInputOutput)currentPair.First;
                    currentKey     = (TLeftKey)currentPair.Second;
                    return(true);
                }

                return(false);
            }
            //---------------------------------------------------------------------------------------
            // Straightforward IEnumerator<T> methods.
            //

            internal override bool MoveNext(ref TOutput currentElement, ref Pair <TLeftKey, int> currentKey)
            {
                while (true)
                {
                    if (_currentRightSource == null)
                    {
                        _mutables = new Mutables();

                        // Check cancellation every few lhs-enumerations in case none of them are producing
                        // any outputs.  Otherwise, we rely on the consumer of this operator to be performing the checks.
                        if ((_mutables._lhsCount++ & CancellationState.POLL_INTERVAL) == 0)
                        {
                            CancellationState.ThrowIfCanceled(_cancellationToken);
                        }

                        // We don't have a "current" right enumerator to use. We have to fetch the next
                        // one. If the left has run out of elements, however, we're done and just return
                        // false right away.

                        if (!_leftSource.MoveNext(ref _mutables._currentLeftElement, ref _mutables._currentLeftKey))
                        {
                            return(false);
                        }

                        // Use the source selection routine to create a right child.
                        IEnumerable <TRightInput> rightChild = _selectManyOperator._rightChildSelector(_mutables._currentLeftElement);

                        Debug.Assert(rightChild != null);
                        _currentRightSource = rightChild.GetEnumerator();

                        Debug.Assert(_currentRightSource != null);

                        // If we have no result selector, we will need to access the Current element of the right
                        // data source as though it is a TOutput. Unfortunately, we know that TRightInput must
                        // equal TOutput (we check it during operator construction), but the type system doesn't.
                        // Thus we would have to cast the result of invoking Current from type TRightInput to
                        // TOutput. This is no good, since the results could be value types. Instead, we save the
                        // enumerator object as an IEnumerator<TOutput> and access that later on.
                        if (_selectManyOperator._resultSelector == null)
                        {
                            _currentRightSourceAsOutput = (IEnumerator <TOutput>)_currentRightSource;
                            Debug.Assert(_currentRightSourceAsOutput == _currentRightSource,
                                         "these must be equal, otherwise the surrounding logic will be broken");
                        }
                    }

                    if (_currentRightSource.MoveNext())
                    {
                        _mutables._currentRightSourceIndex++;

                        // If the inner data source has an element, we can yield it.
                        if (_selectManyOperator._resultSelector != null)
                        {
                            // In the case of a selection function, use that to yield the next element.
                            currentElement = _selectManyOperator._resultSelector(_mutables._currentLeftElement, _currentRightSource.Current);
                        }
                        else
                        {
                            // Otherwise, the right input and output types must be the same. We use the
                            // casted copy of the current right source and just return its current element.
                            Debug.Assert(_currentRightSourceAsOutput != null);
                            currentElement = _currentRightSourceAsOutput.Current;
                        }
                        currentKey = new Pair <TLeftKey, int>(_mutables._currentLeftKey, _mutables._currentRightSourceIndex);

                        return(true);
                    }
                    else
                    {
                        // Otherwise, we have exhausted the right data source. Loop back around and try
                        // to get the next left element, then its right, and so on.
                        _currentRightSource.Dispose();
                        _currentRightSource         = null;
                        _currentRightSourceAsOutput = null;
                    }
                }
            }
        //---------------------------------------------------------------------------------------
        // Called when this enumerator is first enumerated; it must walk through the source
        // and redistribute elements to their slot in the exchange matrix.
        //

        private void EnumerateAndRedistributeElements()
        {
            Mutables mutables = m_mutables;

            Contract.Assert(mutables != null);

            ListChunk <Pair <TInputOutput, THashKey> >[] privateBuffers = new ListChunk <Pair <TInputOutput, THashKey> > [m_partitionCount];
            ListChunk <TOrderKey>[] privateKeyBuffers = new ListChunk <TOrderKey> [m_partitionCount];

            TInputOutput element   = default(TInputOutput);
            TOrderKey    key       = default(TOrderKey);
            int          loopCount = 0;

            while (m_source.MoveNext(ref element, ref key))
            {
                if ((loopCount++ & CancellationState.POLL_INTERVAL) == 0)
                {
                    CancellationState.ThrowIfCanceled(m_cancellationToken);
                }

                // Calculate the element's destination partition index, placing it into the
                // appropriate buffer from which partitions will later enumerate.
                int      destinationIndex;
                THashKey elementHashKey = default(THashKey);
                if (m_keySelector != null)
                {
                    elementHashKey   = m_keySelector(element);
                    destinationIndex = m_repartitionStream.GetHashCode(elementHashKey) % m_partitionCount;
                }
                else
                {
                    Contract.Assert(typeof(THashKey) == typeof(NoKeyMemoizationRequired));
                    destinationIndex = m_repartitionStream.GetHashCode(element) % m_partitionCount;
                }

                Contract.Assert(0 <= destinationIndex && destinationIndex < m_partitionCount,
                                "destination partition outside of the legal range of partitions");

                // Get the buffer for the destnation partition, lazily allocating if needed.  We maintain
                // this list in our own private cache so that we avoid accessing shared memory locations
                // too much.  In the original implementation, we'd access the buffer in the matrix ([N,M],
                // where N is the current partition and M is the destination), but some rudimentary
                // performance profiling indicates copying at the end performs better.
                ListChunk <Pair <TInputOutput, THashKey> > buffer = privateBuffers[destinationIndex];
                ListChunk <TOrderKey> keyBuffer = privateKeyBuffers[destinationIndex];
                if (buffer == null)
                {
                    const int INITIAL_PRIVATE_BUFFER_SIZE = 128;
                    Contract.Assert(keyBuffer == null);
                    privateBuffers[destinationIndex]    = buffer = new ListChunk <Pair <TInputOutput, THashKey> >(INITIAL_PRIVATE_BUFFER_SIZE);
                    privateKeyBuffers[destinationIndex] = keyBuffer = new ListChunk <TOrderKey>(INITIAL_PRIVATE_BUFFER_SIZE);
                }

                buffer.Add(new Pair <TInputOutput, THashKey>(element, elementHashKey));
                keyBuffer.Add(key);
            }

            // Copy the local buffers to the shared space and then signal to other threads that
            // we are done.  We can then immediately move on to enumerating the elements we found
            // for the current partition before waiting at the barrier.  If we found a lot, we will
            // hopefully never have to physically wait.
            for (int i = 0; i < m_partitionCount; i++)
            {
                m_valueExchangeMatrix[m_partitionIndex, i] = privateBuffers[i];
                m_keyExchangeMatrix[m_partitionIndex, i]   = privateKeyBuffers[i];
            }

            m_barrier.Signal();

            // Begin at our own buffer.
            mutables.m_currentBufferIndex = m_partitionIndex;
            mutables.m_currentBuffer      = privateBuffers[m_partitionIndex];
            mutables.m_currentKeyBuffer   = privateKeyBuffers[m_partitionIndex];
            mutables.m_currentIndex       = ENUMERATION_NOT_STARTED;
        }
예제 #30
0
            //---------------------------------------------------------------------------------------
            // This API, upon the first time calling it, walks the entire source query tree. It begins
            // with an accumulator value set to the aggregation operator's seed, and always passes
            // the accumulator along with the current element from the data source to the binary
            // intermediary aggregation operator. The return value is kept in the accumulator. At
            // the end, we will have our intermediate result, ready for final aggregation.
            //

            internal override bool MoveNext(ref TIntermediate currentElement, ref int currentKey)
            {
                Contract.Assert(_reduceOperator != null);
                Contract.Assert(_reduceOperator._intermediateReduce != null, "expected a compiled operator");

                // Only produce a single element.  Return false if MoveNext() was already called before.
                if (_accumulated)
                {
                    return(false);
                }
                _accumulated = true;

                bool          hadNext     = false;
                TIntermediate accumulator = default(TIntermediate);

                // Initialize the accumulator.
                if (_reduceOperator._seedIsSpecified)
                {
                    // If the seed is specified, initialize accumulator to the seed value.
                    accumulator = _reduceOperator._seedFactory == null
                                      ? _reduceOperator._seed
                                      : _reduceOperator._seedFactory();
                }
                else
                {
                    // If the seed is not specified, then we take the first element as the seed.
                    // Seed may be unspecified only if TInput is the same as TIntermediate.
                    Contract.Assert(typeof(TInput) == typeof(TIntermediate));

                    TInput acc          = default(TInput);
                    TKey   accKeyUnused = default(TKey);
                    if (!_source.MoveNext(ref acc, ref accKeyUnused))
                    {
                        return(false);
                    }
                    hadNext     = true;
                    accumulator = (TIntermediate)((object)acc);
                }

                // Scan through the source and accumulate the result.
                TInput input     = default(TInput);
                TKey   keyUnused = default(TKey);
                int    i         = 0;

                while (_source.MoveNext(ref input, ref keyUnused))
                {
                    if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                    {
                        CancellationState.ThrowIfCanceled(_cancellationToken);
                    }
                    hadNext     = true;
                    accumulator = _reduceOperator._intermediateReduce(accumulator, input);
                }

                if (hadNext)
                {
                    currentElement = accumulator;
                    currentKey     = _partitionIndex; // A reduction's "index" is just its partition number.
                    return(true);
                }

                return(false);
            }