Chunked List
//http://isotopescreencapture.codeplex.com/ //The MIT License (MIT) using System.Collections.Generic; namespace Isotope.Collections { public class ChunkedList<T> : IEnumerable<Isotope.Collections.ChunkedList<T>.RowEnumerator> { private readonly List<T> data; private readonly int _chunkSize; public ChunkedList(int chunksize, int capacity) { if (chunksize < 1) { throw new System.ArgumentOutOfRangeException("chunksize", "must be at least 1"); } this._chunkSize = chunksize; this.data = new List<T>(chunksize * capacity); } public T[] ToArray() { return this.data.ToArray(); } public void Add(params T[] items) { this.AddChunk(items); } public void AddChunk(ICollection<T> items) { if (items.Count != _chunkSize) { string msg = string.Format("must add exactly {0} items", items.Count); throw new System.ArgumentOutOfRangeException(msg); } this.data.AddRange(items); if (this.data.Count % this._chunkSize != 0) { throw new System.Exception("Did not maintain consistency of chunked list"); } } public int Count { get { return this.data.Count / this._chunkSize; } } public int ChunkSize { get { return _chunkSize; } } public void GetRow(int r, T[] row_array) { int startindex = r * this._chunkSize; for (int c = 0; c < this._chunkSize; c++) { row_array[c] = this.data[startindex + c]; } } public T[] GetRow(int r) { var a = new T[this._chunkSize]; this.GetRow(r, a); return a; } public T this[int row, int col] { get { if (row < 0) { throw new System.ArgumentOutOfRangeException("row", "must be greater than zero"); } if (col < 0) { throw new System.ArgumentOutOfRangeException("col", "must be greater than zero"); } if (row >= this.Count) { throw new System.ArgumentOutOfRangeException("row"); } if (col >= this._chunkSize) { throw new System.ArgumentOutOfRangeException("col"); } return this.data[(row * this._chunkSize) + col]; } } // Implement IEnumerable<T> System.Collections.Generic.IEnumerator<RowEnumerator> System.Collections.Generic.IEnumerable<RowEnumerator>.GetEnumerator() { return this.AsEnumerable().GetEnumerator(); } // Implement IEnumerable System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.AsEnumerable().GetEnumerator(); } private T[] CreateRowBuffer() { var row = new T[this._chunkSize]; return row; } private IEnumerable<RowEnumerator> AsEnumerable() { var row_array = this.CreateRowBuffer(); for (int r = 0; r < this.Count; r++) { this.GetRow(r, row_array); yield return new RowEnumerator(r, row_array); } } public struct RowEnumerator { public readonly int Index; public readonly T[] ItemArray; internal RowEnumerator(int index, T[] itemarray) { this.Index = index; this.ItemArray = itemarray; } } } }