| File: System\Linq\Parallel\Utils\ListChunk.cs | Web Access |
| Project: src\runtime\src\libraries\System.Linq.Parallel\src\System.Linq.Parallel.csproj (System.Linq.Parallel) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // ListChunk.cs // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System.Collections.Generic; using System.Diagnostics; namespace System.Linq.Parallel { /// <summary> /// A linked list of array chunks. Allows direct access to its arrays. /// </summary> /// <typeparam name="TInputOutput">The elements held within.</typeparam> internal sealed class ListChunk<TInputOutput> : IEnumerable<TInputOutput> { internal TInputOutput[] _chunk; private int _chunkCount; private ListChunk<TInputOutput>? _nextChunk; private ListChunk<TInputOutput> _tailChunk; /// <summary> /// Allocates a new root chunk of a particular size. /// </summary> internal ListChunk(int size) { Debug.Assert(size > 0); _chunk = new TInputOutput[size]; _chunkCount = 0; _tailChunk = this; } /// <summary> /// Adds an element to this chunk. Only ever called on the root. /// </summary> /// <param name="e">The new element.</param> internal void Add(TInputOutput e) { ListChunk<TInputOutput> tail = _tailChunk; if (tail._chunkCount == tail._chunk.Length) { _tailChunk = new ListChunk<TInputOutput>(tail._chunkCount * 2); tail = (tail._nextChunk = _tailChunk); } tail._chunk[tail._chunkCount++] = e; } /// <summary> /// The next chunk in the linked chain. /// </summary> internal ListChunk<TInputOutput>? Next { get { return _nextChunk; } } /// <summary> /// The number of elements contained within this particular chunk. /// </summary> internal int Count { get { return _chunkCount; } } /// <summary> /// Fetches an enumerator to walk the elements in all chunks rooted from this one. /// </summary> public IEnumerator<TInputOutput> GetEnumerator() { ListChunk<TInputOutput>? curr = this; while (curr != null) { for (int i = 0; i < curr._chunkCount; i++) { yield return curr._chunk[i]; } Debug.Assert(curr._chunkCount == curr._chunk.Length || curr._nextChunk == null); curr = curr._nextChunk; } } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return ((IEnumerable<TInputOutput>)this).GetEnumerator(); } } }