3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
10 // <OWNER>Microsoft</OWNER>
12 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
14 using System.Collections.Generic;
15 using System.Diagnostics.Contracts;
17 namespace System.Linq.Parallel
20 /// A linked list of array chunks. Allows direct access to its arrays.
22 /// <typeparam name="TInputOutput">The elements held within.</typeparam>
23 internal class ListChunk<TInputOutput> : IEnumerable<TInputOutput>
25 internal TInputOutput[] m_chunk;
26 private int m_chunkCount;
27 private ListChunk<TInputOutput> m_nextChunk;
28 private ListChunk<TInputOutput> m_tailChunk;
31 /// Allocates a new root chunk of a particular size.
33 internal ListChunk(int size)
35 Contract.Assert(size > 0);
36 m_chunk = new TInputOutput[size];
42 /// Adds an element to this chunk. Only ever called on the root.
44 /// <param name="e">The new element.</param>
45 internal void Add(TInputOutput e)
47 ListChunk<TInputOutput> tail = m_tailChunk;
48 if (tail.m_chunkCount == tail.m_chunk.Length)
50 m_tailChunk = new ListChunk<TInputOutput>(tail.m_chunkCount * 2);
51 tail = (tail.m_nextChunk = m_tailChunk);
54 tail.m_chunk[tail.m_chunkCount++] = e;
58 /// The next chunk in the linked chain.
60 internal ListChunk<TInputOutput> Next
62 get { return m_nextChunk; }
66 /// The number of elements contained within this particular chunk.
70 get { return m_chunkCount; }
74 /// Fetches an enumerator to walk the elements in all chunks rooted from this one.
76 public IEnumerator<TInputOutput> GetEnumerator()
78 ListChunk<TInputOutput> curr = this;
81 for (int i = 0; i < curr.m_chunkCount; i++)
83 yield return curr.m_chunk[i];
85 Contract.Assert(curr.m_chunkCount == curr.m_chunk.Length || curr.m_nextChunk == null);
86 curr = curr.m_nextChunk;
90 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
92 return ((IEnumerable<TInputOutput>)this).GetEnumerator();