Sequence is an abstraction of a data reseqeuncer
using System; using System.Collections.Generic; namespace TradeHelp.Utilities { /// <summary> /// Sequence is an abstraction of a data reseqeuncer /// </summary> public class Sequencer<T> { private int? _curNum; private int _subIndex; private readonly List<Data> _data = new List<Data>(); /// <summary> /// Takes as input data of type T and returns all data as a contiguous /// block of reseqeunced data. /// </summary> /// <param name="data">the data to be re-sequenced</param> /// <param name="sequenceNum">the seqence number associated with the data</param> /// <param name="initial">indicates if this sequenceNum is the first in the sequence</param> /// <returns>contiguous sequence of data</returns> public IEnumerable<T> Resequence(T data, int sequenceNum, bool initial) { if (initial) { if (_curNum.HasValue) throw new Exception(); _curNum = sequenceNum; } else if (sequenceNum < _curNum) { throw new ArgumentOutOfRangeException(); } var temp = new Data(data, sequenceNum, ++_subIndex); var index = _data.BinarySearch(temp); if (index > 0) throw new Exception(); _data.Insert(~index, temp); return Enumerate(); } /// <summary> /// Takes as input a collection of data of type T and returns all data as a contiguous /// block of reseqeunced data. /// </summary> /// <param name="collection">the data to be re-sequenced</param> /// <param name="sequenceNum">the seqence number associated with the data</param> /// <param name="initial">indicates if this sequenceNum is the first in the sequence</param> /// <returns>contiguous sequence of data</returns> public IEnumerable<T> Resequence(ICollection<T> collection, int sequenceNum, bool initial) { Invariant.CheckIsNull(collection, "collection"); if (initial) { if (_curNum.HasValue) throw new Exception(); _curNum = sequenceNum; } else if (sequenceNum < _curNum) { throw new ArgumentOutOfRangeException(); } if (collection.Count == 0) { var temp = new Data(sequenceNum, ++_subIndex); var index = _data.BinarySearch(temp); if (index > 0) throw new Exception(); _data.Insert(~index, temp); } else { foreach (var data in collection) { var temp = new Data(data, sequenceNum, ++_subIndex); var index = _data.BinarySearch(temp); if (index > 0) throw new Exception(); _data.Insert(~index, temp); } } return Enumerate(); } private IEnumerable<T> Enumerate() { while (_data.Count > 0 && _data[0].Index1 == _curNum) { while (_data.Count > 0 && _data[0].Index1 == _curNum) { if (_data[0].HasData) { yield return _data[0].TData; } _data.RemoveAt(0); } _curNum++; } } private struct Data : IComparable<Data> { public Data(int index1, int index2) { Index1 = index1; Index2 = index2; HasData = false; TData = default(T); } public Data(T data, int index1, int index2) { TData = data; Index1 = index1; Index2 = index2; HasData = true; } public readonly T TData; public readonly int Index1; public readonly int Index2; public readonly bool HasData; public int CompareTo(Data other) { if (Index1 == other.Index1) { return Comparer<int>.Default.Compare(Index2, other.Index2); } return Comparer<int>.Default.Compare(Index1, other.Index1); } } } }