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);
}
}
}
}
Related examples in the same category