Esempio n. 1
0
 internal OrderedGroupByGrouping(TGroupKey groupKey, IComparer <TOrderKey> orderComparer)
 {
     this.m_groupKey      = groupKey;
     this.m_values        = new GrowingArray <TElement>();
     this.m_orderKeys     = new GrowingArray <TOrderKey>();
     this.m_orderComparer = orderComparer;
 }
Esempio n. 2
0
        /// <summary>
        /// No more elements will be added, so we can sort the group now.
        /// </summary>
        internal void DoneAdding()
        {
            Debug.Assert(_values != null);
            Debug.Assert(_orderKeys != null);

            // Create a map of key-value pair.
            // We can't use a dictionary since the keys are not necessarily unique
            List <KeyValuePair <TOrderKey, TElement> > sortedValues = new List <KeyValuePair <TOrderKey, TElement> >();

            for (int i = 0; i < _orderKeys.InternalArray.Length; i++)
            {
                sortedValues.Add(new KeyValuePair <TOrderKey, TElement>(_orderKeys.InternalArray[i], _values.InternalArray[i]));
            }

            // Sort the values by using the _orderComparer wrapped in a Tuple comparer
            sortedValues.Sort(0, _values.Count, _wrappedComparer);

            // Un-pack the values from the list back into the 2 separate arrays
            for (int i = 0; i < _values.InternalArray.Length; i++)
            {
                _orderKeys.InternalArray[i] = sortedValues[i].Key;
                _values.InternalArray[i]    = sortedValues[i].Value;
            }
#if DEBUG
            _orderKeys = null; // Any future calls to Add() or DoneAdding() will fail
#endif
        }
        private void BuildKeysFromSource(ref GrowingArray <TKey> keys, ref List <TInputOutput> values)
        {
            values = new List <TInputOutput>();
            CancellationToken mergedCancellationToken = this.m_groupState.CancellationState.MergedCancellationToken;

            try
            {
                TInputOutput currentElement = default(TInputOutput);
                TKey         currentKey     = default(TKey);
                bool         flag           = this.m_source.MoveNext(ref currentElement, ref currentKey);
                if (keys == null)
                {
                    keys = new GrowingArray <TKey>();
                }
                if (flag)
                {
                    int num = 0;
                    do
                    {
                        if ((num++ & 0x3f) == 0)
                        {
                            CancellationState.ThrowIfCanceled(mergedCancellationToken);
                        }
                        keys.Add(currentKey);
                        values.Add(currentElement);
                    }while (this.m_source.MoveNext(ref currentElement, ref currentKey));
                }
            }
            finally
            {
                this.m_source.Dispose();
            }
        }
 private void QuickSortIndicesInPlace(GrowingArray <TKey> keys, List <TInputOutput> values, OrdinalIndexState ordinalIndexState)
 {
     int[] indices = new int[values.Count];
     for (int i = 0; i < indices.Length; i++)
     {
         indices[i] = i;
     }
     if ((indices.Length > 1) && ordinalIndexState.IsWorseThan(OrdinalIndexState.Increasing))
     {
         this.QuickSort(0, indices.Length - 1, keys.InternalArray, indices, this.m_groupState.CancellationState.MergedCancellationToken);
     }
     if (this.m_partitionCount == 1)
     {
         TInputOutput[] localArray = new TInputOutput[values.Count];
         for (int j = 0; j < indices.Length; j++)
         {
             localArray[j] = values[indices[j]];
         }
         this.m_sharedValues[this.m_partitionIndex] = localArray;
     }
     else
     {
         this.m_sharedIndices[this.m_partitionIndex] = indices;
         this.m_sharedKeys[this.m_partitionIndex]    = keys;
         this.m_sharedValues[this.m_partitionIndex]  = new TInputOutput[values.Count];
         values.CopyTo(this.m_sharedValues[this.m_partitionIndex]);
     }
 }
Esempio n. 5
0
        private KeyAndValuesComparer _wrappedComparer; // Comparer that wraps the _orderComparer used for sorting key/value pairs

        /// <summary>
        /// Constructs a new grouping
        /// </summary>
        internal OrderedGroupByGrouping(
            TGroupKey groupKey,
            IComparer <TOrderKey> orderComparer)
        {
            _groupKey        = groupKey;
            _values          = new GrowingArray <TElement>();
            _orderKeys       = new GrowingArray <TOrderKey>();
            _orderComparer   = orderComparer;
            _wrappedComparer = new KeyAndValuesComparer(_orderComparer);
        }
        internal override TInputOutput[] Sort()
        {
            GrowingArray <TKey> keys   = null;
            List <TInputOutput> values = null;

            this.BuildKeysFromSource(ref keys, ref values);
            this.QuickSortIndicesInPlace(keys, values, this.m_indexState);
            if (this.m_partitionCount > 1)
            {
                this.MergeSortCooperatively();
            }
            return(this.m_sharedValues[this.m_partitionIndex]);
        }
Esempio n. 7
0
        /// <summary>
        /// No more elements will be added, so we can sort the group now.
        /// </summary>
        internal void DoneAdding()
        {
            Contract.Assert(m_values != null);
            Contract.Assert(m_orderKeys != null);

            Array.Sort(
                m_orderKeys.InternalArray, m_values.InternalArray,
                0, m_values.Count,
                m_orderComparer);

#if DEBUG
            m_orderKeys = null; // Any future calls to Add() or DoneAdding() will fail
#endif
        }
        internal static SortHelper <TInputOutput, TKey>[] GenerateSortHelpers(PartitionedStream <TInputOutput, TKey> partitions, QueryTaskGroupState groupState)
        {
            int partitionCount = partitions.PartitionCount;

            SortHelper <TInputOutput, TKey>[] helperArray = new SortHelper <TInputOutput, TKey> [partitionCount];
            int num2 = 1;
            int num3 = 0;

            while (num2 < partitionCount)
            {
                num3++;
                num2 = num2 << 1;
            }
            int[][] sharedIndices              = new int[partitionCount][];
            GrowingArray <TKey>[] sharedkeys   = new GrowingArray <TKey> [partitionCount];
            TInputOutput[][]      sharedValues = new TInputOutput[partitionCount][];
            Barrier[,] sharedBarriers = new Barrier[num3, partitionCount];
            if (partitionCount > 1)
            {
                int num4 = 1;
                for (int j = 0; j < sharedBarriers.GetLength(0); j++)
                {
                    for (int k = 0; k < sharedBarriers.GetLength(1); k++)
                    {
                        if ((k % num4) == 0)
                        {
                            sharedBarriers[j, k] = new Barrier(2);
                        }
                    }
                    num4 *= 2;
                }
            }
            for (int i = 0; i < partitionCount; i++)
            {
                helperArray[i] = new SortHelper <TInputOutput, TKey>(partitions[i], partitionCount, i, groupState, sharedIndices, partitions.OrdinalIndexState, partitions.KeyComparer, sharedkeys, sharedValues, sharedBarriers);
            }
            return(helperArray);
        }
        private void MergeSortCooperatively()
        {
            CancellationToken mergedCancellationToken = this.m_groupState.CancellationState.MergedCancellationToken;
            int length = this.m_sharedBarriers.GetLength(0);

            for (int i = 0; i < length; i++)
            {
                bool flag = i == (length - 1);
                int  num3 = this.ComputePartnerIndex(i);
                if (num3 < this.m_partitionCount)
                {
                    int[] numArray               = this.m_sharedIndices[this.m_partitionIndex];
                    GrowingArray <TKey> array    = this.m_sharedKeys[this.m_partitionIndex];
                    TKey[]         internalArray = array.InternalArray;
                    TInputOutput[] sourceArray   = this.m_sharedValues[this.m_partitionIndex];
                    this.m_sharedBarriers[i, Math.Min(this.m_partitionIndex, num3)].SignalAndWait(mergedCancellationToken);
                    if (this.m_partitionIndex >= num3)
                    {
                        this.m_sharedBarriers[i, num3].SignalAndWait(mergedCancellationToken);
                        int[]               numArray4   = this.m_sharedIndices[this.m_partitionIndex];
                        TKey[]              localArray6 = this.m_sharedKeys[this.m_partitionIndex].InternalArray;
                        TInputOutput[]      localArray7 = this.m_sharedValues[this.m_partitionIndex];
                        int[]               numArray5   = this.m_sharedIndices[num3];
                        GrowingArray <TKey> array2      = this.m_sharedKeys[num3];
                        TInputOutput[]      localArray8 = this.m_sharedValues[num3];
                        int destinationIndex            = localArray7.Length;
                        int num12 = sourceArray.Length;
                        int num13 = destinationIndex + num12;
                        int num14 = (num13 + 1) / 2;
                        int num15 = num13 - 1;
                        int num16 = destinationIndex - 1;
                        int num17 = num12 - 1;
                        while (num15 >= num14)
                        {
                            if ((num15 & 0x3f) == 0)
                            {
                                CancellationState.ThrowIfCanceled(mergedCancellationToken);
                            }
                            if ((num16 >= 0) && ((num17 < 0) || (this.m_keyComparer.Compare(localArray6[numArray4[num16]], internalArray[numArray[num17]]) > 0)))
                            {
                                if (flag)
                                {
                                    localArray8[num15] = localArray7[numArray4[num16]];
                                }
                                else
                                {
                                    numArray5[num15] = numArray4[num16];
                                }
                                num16--;
                            }
                            else
                            {
                                if (flag)
                                {
                                    localArray8[num15] = sourceArray[numArray[num17]];
                                }
                                else
                                {
                                    numArray5[num15] = destinationIndex + numArray[num17];
                                }
                                num17--;
                            }
                            num15--;
                        }
                        if (!flag && (sourceArray.Length > 0))
                        {
                            array2.CopyFrom(internalArray, sourceArray.Length);
                            Array.Copy(sourceArray, 0, localArray8, destinationIndex, sourceArray.Length);
                        }
                        this.m_sharedBarriers[i, num3].SignalAndWait(mergedCancellationToken);
                        return;
                    }
                    int[]          numArray2   = this.m_sharedIndices[num3];
                    TKey[]         localArray3 = this.m_sharedKeys[num3].InternalArray;
                    TInputOutput[] localArray4 = this.m_sharedValues[num3];
                    this.m_sharedIndices[num3] = numArray;
                    this.m_sharedKeys[num3]    = array;
                    this.m_sharedValues[num3]  = sourceArray;
                    int            num4             = sourceArray.Length;
                    int            num5             = localArray4.Length;
                    int            num6             = num4 + num5;
                    int[]          numArray3        = null;
                    TInputOutput[] destinationArray = new TInputOutput[num6];
                    if (!flag)
                    {
                        numArray3 = new int[num6];
                    }
                    this.m_sharedIndices[this.m_partitionIndex] = numArray3;
                    this.m_sharedKeys[this.m_partitionIndex]    = array;
                    this.m_sharedValues[this.m_partitionIndex]  = destinationArray;
                    this.m_sharedBarriers[i, this.m_partitionIndex].SignalAndWait(mergedCancellationToken);
                    int num7  = (num6 + 1) / 2;
                    int index = 0;
                    int num9  = 0;
                    int num10 = 0;
                    while (index < num7)
                    {
                        if ((index & 0x3f) == 0)
                        {
                            CancellationState.ThrowIfCanceled(mergedCancellationToken);
                        }
                        if ((num9 < num4) && ((num10 >= num5) || (this.m_keyComparer.Compare(internalArray[numArray[num9]], localArray3[numArray2[num10]]) <= 0)))
                        {
                            if (flag)
                            {
                                destinationArray[index] = sourceArray[numArray[num9]];
                            }
                            else
                            {
                                numArray3[index] = numArray[num9];
                            }
                            num9++;
                        }
                        else
                        {
                            if (flag)
                            {
                                destinationArray[index] = localArray4[numArray2[num10]];
                            }
                            else
                            {
                                numArray3[index] = num4 + numArray2[num10];
                            }
                            num10++;
                        }
                        index++;
                    }
                    if (!flag && (num4 > 0))
                    {
                        Array.Copy(sourceArray, 0, destinationArray, 0, num4);
                    }
                    this.m_sharedBarriers[i, this.m_partitionIndex].SignalAndWait(mergedCancellationToken);
                }
            }
        }