SortQueryOperator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Linq / Parallel / QueryOperators / Unary / SortQueryOperator.cs / 1305376 / SortQueryOperator.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// 
// SortQueryOperator.cs 
//
// [....] 
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

using System.Collections.Generic; 
using System.Diagnostics.Contracts;
using System.Threading; 
 
namespace System.Linq.Parallel
{ 
    /// 
    /// The query operator for OrderBy and ThenBy.
    /// 
    ///  
    /// 
    internal sealed class SortQueryOperator : 
        UnaryQueryOperator, IOrderedEnumerable 
    {
        private readonly Func m_keySelector; // Key selector used when sorting. 
        private readonly IComparer m_comparer; // Key comparison logic to use during sorting.

        //----------------------------------------------------------------------------------------
        // Instantiates a new sort operator. 
        //
 
        internal SortQueryOperator(IEnumerable source, Func keySelector, 
                                   IComparer comparer, bool descending)
            : base(source, true) 
        {
            Contract.Assert(keySelector != null, "key selector must not be null");

            m_keySelector = keySelector; 

            // If a comparer wasn't supplied, we use the default one for the key type. 
            if (comparer == null) 
            {
                m_comparer = Util.GetDefaultComparer(); 
            }
            else
            {
                m_comparer = comparer; 
            }
 
            if (descending) 
            {
                m_comparer = new ReverseComparer(m_comparer); 
            }

            SetOrdinalIndexState(OrdinalIndexState.Shuffled);
        } 

        //--------------------------------------------------------------------------------------- 
        // IOrderedEnumerable method for nesting an order by operator inside another. 
        //
 
        IOrderedEnumerable IOrderedEnumerable.CreateOrderedEnumerable(
            Func key2Selector, IComparer key2Comparer, bool descending)
        {
            key2Comparer = key2Comparer ?? Util.GetDefaultComparer(); 

            if (descending) 
            { 
                key2Comparer = new ReverseComparer(key2Comparer);
            } 

            IComparer> pairComparer = new PairComparer(m_comparer, key2Comparer);
            Func> pairKeySelector =
                (TInputOutput elem) => new Pair(m_keySelector(elem), key2Selector(elem)); 

            return new SortQueryOperator>(Child, pairKeySelector, pairComparer, false); 
        } 

        //--------------------------------------------------------------------------------------- 
        // Accessor the the key selector.
        //

        internal Func KeySelector 
        {
            get { return m_keySelector; } 
        } 

        //--------------------------------------------------------------------------------------- 
        // Accessor the the key comparer.
        //

        internal IComparer KeyComparer 
        {
            get { return m_comparer; } 
        } 

        //---------------------------------------------------------------------------------------- 
        // Opens the current operator. This involves opening the child operator tree, enumerating
        // the results, sorting them, and then returning an enumerator that walks the result.
        //
 
        internal override QueryResults Open(QuerySettings settings, bool preferStriping)
        { 
            QueryResults childQueryResults = Child.Open(settings, false); 
            return new SortQueryOperatorResults(childQueryResults, this, settings, preferStriping);
        } 


        internal override void WrapPartitionedStream(
            PartitionedStream inputStream, IPartitionedStreamRecipient recipient, bool preferStriping, QuerySettings settings) 
        {
            PartitionedStream outputStream = 
                new PartitionedStream(inputStream.PartitionCount, this.m_comparer, OrdinalIndexState); 

            for (int i = 0; i < outputStream.PartitionCount; i++) 
            {
                outputStream[i] = new SortQueryOperatorEnumerator(
                    inputStream[i], m_keySelector, m_comparer);
            } 

            recipient.Receive(outputStream); 
        } 

        //--------------------------------------------------------------------------------------- 
        // Returns an enumerable that represents the query executing sequentially.
        //

        internal override IEnumerable AsSequentialQuery(CancellationToken token) 
        {
            IEnumerable wrappedChild = CancellableEnumerable.Wrap(Child.AsSequentialQuery(token), token); 
            return wrappedChild.OrderBy(m_keySelector, m_comparer); 
        }
 
        //----------------------------------------------------------------------------------------
        // Whether this operator performs a premature merge.
        //
 
        internal override bool LimitsParallelism
        { 
            get { return false; } 
        }
    } 

    internal class SortQueryOperatorResults : QueryResults
    {
        protected QueryResults m_childQueryResults; // Results of the child query 
        private SortQueryOperator m_op; // Operator that generated these results
        private QuerySettings m_settings; // Settings collected from the query 
        private bool m_preferStriping; // If the results are indexible, should we use striping when partitioning them 

        internal SortQueryOperatorResults( 
            QueryResults childQueryResults, SortQueryOperator op,
            QuerySettings settings, bool preferStriping)
        {
            m_childQueryResults = childQueryResults; 
            m_op = op;
            m_settings = settings; 
            m_preferStriping = preferStriping; 
        }
 
        internal override bool IsIndexible
        {
            get { return false; }
        } 

        internal override void GivePartitionedStream(IPartitionedStreamRecipient recipient) 
        { 
            m_childQueryResults.GivePartitionedStream(new ChildResultsRecipient(recipient, m_op, m_settings));
        } 

        private class ChildResultsRecipient : IPartitionedStreamRecipient
        {
            IPartitionedStreamRecipient m_outputRecipient; 
            SortQueryOperator m_op;
            QuerySettings m_settings; 
 
            internal ChildResultsRecipient(IPartitionedStreamRecipient outputRecipient, SortQueryOperator op, QuerySettings settings)
            { 
                m_outputRecipient = outputRecipient;
                m_op = op;
                m_settings = settings;
            } 

            public void Receive(PartitionedStream childPartitionedStream) 
            { 
                m_op.WrapPartitionedStream(childPartitionedStream, m_outputRecipient, false, m_settings);
            } 
        }
    }

    //---------------------------------------------------------------------------------------- 
    // This enumerator performs sorting based on a key selection and comparison routine.
    // 
 
    internal class SortQueryOperatorEnumerator : QueryOperatorEnumerator
    { 
        private readonly QueryOperatorEnumerator m_source; // Data source to sort.
        private readonly Func m_keySelector; // Key selector used when sorting.
        private readonly IComparer m_keyComparer; // Key comparison logic to use during sorting.
 
        //---------------------------------------------------------------------------------------
        // Instantiates a new sort operator enumerator. 
        // 

        internal SortQueryOperatorEnumerator(QueryOperatorEnumerator source, 
            Func keySelector, IComparer keyComparer)
        {
            Contract.Assert(source != null);
            Contract.Assert(keySelector != null, "need a key comparer"); 
            Contract.Assert(keyComparer != null, "expected a compiled operator");
 
            m_source = source; 
            m_keySelector = keySelector;
            m_keyComparer = keyComparer; 
        }
        //----------------------------------------------------------------------------------------
        // Accessor for the key comparison routine.
        // 

        public IComparer KeyComparer 
        { 
            get { return m_keyComparer; }
        } 

        //---------------------------------------------------------------------------------------
        // Moves to the next element in the sorted output. When called for the first time, the
        // descendents in the sort's child tree are executed entirely, the results accumulated 
        // in memory, and the data sorted.
        // 
 
        internal override bool MoveNext(ref TInputOutput currentElement, ref TSortKey currentKey)
        { 
            Contract.Assert(m_source != null);

            TKey keyUnused = default(TKey);
            if (!m_source.MoveNext(ref currentElement, ref keyUnused)) 
            {
                return false; 
            } 

            currentKey = m_keySelector(currentElement); 
            return true;
        }

        protected override void Dispose(bool disposing) 
        {
            Contract.Assert(m_source != null); 
            m_source.Dispose(); 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK