RepeatEnumerable.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 / Enumerables / RepeatEnumerable.cs / 1305376 / RepeatEnumerable.cs

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

using System.Collections.Generic; 
using System.Diagnostics.Contracts;
 
namespace System.Linq.Parallel 
{
    ///  
    /// A simple enumerable type that implements the repeat algorithm. It also supports
    /// partitioning of the count space by implementing an interface that PLINQ recognizes.
    /// 
    ///  
    internal class RepeatEnumerable : ParallelQuery, IParallelPartitionable
    { 
 
        private TResult m_element; // Element value to repeat.
        private int m_count; // Count of element values. 

        //------------------------------------------------------------------------------------
        // Constructs a new repeat enumerable object for the repeat operation.
        // 

        internal RepeatEnumerable(TResult element, int count) 
            : base(QuerySettings.Empty) 
        {
            Contract.Assert(count >= 0, "count not within range (must be >= 0)"); 
            m_element = element;
            m_count = count;
        }
 
        //-----------------------------------------------------------------------------------
        // Retrieves 'count' partitions, dividing the total count by the partition count, 
        // and having each partition produce a certain number of repeated elements. 
        //
 
        public QueryOperatorEnumerator[] GetPartitions(int partitionCount)
        {
            // Calculate a stride size.
            int stride = (m_count + partitionCount - 1) / partitionCount; 

            // Now generate the actual enumerators. Each produces 'stride' elements, except 
            // for the last partition which may produce fewer (if 'm_count' isn't evenly 
            // divisible by 'partitionCount').
            QueryOperatorEnumerator[] partitions = new QueryOperatorEnumerator[partitionCount]; 
            for (int i = 0, offset = 0; i < partitionCount; i++, offset += stride)
            {
                if ((offset + stride) > m_count)
                { 
                    partitions[i] = new RepeatEnumerator(m_element, offset < m_count ? m_count - offset : 0, offset);
                } 
                else 
                {
                    partitions[i] = new RepeatEnumerator(m_element, stride, offset); 
                }
            }

            return partitions; 
        }
 
        //----------------------------------------------------------------------------------- 
        // Basic IEnumerator method implementations.
        // 

        public override IEnumerator GetEnumerator()
        {
            return new RepeatEnumerator(m_element, m_count, 0).AsClassicEnumerator(); 
        }
 
        //----------------------------------------------------------------------------------- 
        // The actual enumerator that produces a set of repeated elements.
        // 

        class RepeatEnumerator : QueryOperatorEnumerator
        {
 
            private readonly TResult m_element; // The element to repeat.
            private readonly int m_count; // The number of times to repeat it. 
            private readonly int m_indexOffset; // Our index offset. 
            private Shared m_currentIndex; // The number of times we have already repeated it. [allocate in moveNext to avoid false-sharing]
 
            //------------------------------------------------------------------------------------
            // Creates a new enumerator.
            //
 
            internal RepeatEnumerator(TResult element, int count, int indexOffset)
            { 
                m_element = element; 
                m_count = count;
                m_indexOffset = indexOffset; 
            }

            //-----------------------------------------------------------------------------------
            // Basic IEnumerator methods. These produce the repeating sequence.. 
            //
 
            internal override bool MoveNext(ref TResult currentElement, ref int currentKey) 
            {
                if( m_currentIndex == null) 
                    m_currentIndex = new Shared(-1);

                if (m_currentIndex.Value < (m_count - 1))
                { 
                    ++m_currentIndex.Value;
                    currentElement = m_element; 
                    currentKey = m_currentIndex.Value + m_indexOffset; 
                    return true;
                } 

                return false;
            }
 
            internal override void Reset()
            { 
                m_currentIndex = null; 
            }
        } 
    }
}

// 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