using System;
/* Circular Buffer Generic Implementation
* By KDERazorback (http://twitter.com/kderazorback)
*
* Fast and Lightweight, Generic Circular Buffer Implementation, supports for bidirectional rotations
* Free to use or modify! Just keep me on the comments!
*/
/// <summary>
/// Used to store a Circular Buffer of objects with a particular size, that rotates when an item is added to the collection.
/// </summary>
class CircularBuffer<T>
{
/// <summary>
/// Creates a new Circular Buffer with the specified Capacity
/// </summary>
/// <param name="capacity">Total elements that can be stored inside the buffer before it starts discarding items</param>
public CircularBuffer(int capacity)
{
plainBuffer = new T[capacity];
_startIndex = 0;
}
private T[] plainBuffer;
private int _startIndex; // Stores the start of the Circular Buffer
/// <summary>
/// Stores the current Capacity of this Buffer
/// </summary>
public int Capacity
{
get { return plainBuffer.Length; }
}
/// <summary>
/// Returns the item that is stored on the specified Index inside the Circular Buffer
/// </summary>
/// <param name="index">Index of the Item to be returned</param>
/// <returns>The object value stored on the specified index</returns>
public T ElementAt(int index)
{
if ((index >= plainBuffer.Length) || (index < 0))
throw new IndexOutOfRangeException();
index += _startIndex;
if (index >= plainBuffer.Length)
index -= plainBuffer.Length;
return plainBuffer[index];
}
/// <summary>
/// Returns an array with the full content of the actual Circular Buffer
/// </summary>
/// <returns></returns>
public T[] ToArray()
{
int i;
T[] output = new T[plainBuffer.Length];
for (i = 0; i < plainBuffer.Length; i++)
{
output[i] = ElementAt(i);
}
return output;
}
/// <summary>
/// Inserts a new item inside the Circular Buffer and rotates the entire structure by one step forwards
/// </summary>
/// <param name="newItem">New item to be inserted into the Circular Buffer</param>
public void Insert(T newItem)
{
if (_startIndex == 0)
_startIndex = plainBuffer.Length - 1;
else
_startIndex--;
plainBuffer[_startIndex] = newItem;
}
/// <summary>
/// Inserts a new item inside the Circular Buffer and rotates the entire structure by one step backwards
/// </summary>
/// <param name="newItem">New item to be inserted into the Circular Buffer</param>
public void InsertBackwards(T newItem)
{
plainBuffer[_startIndex] = newItem;
if (_startIndex == plainBuffer.Length - 1)
_startIndex = 0;
else
_startIndex++;
}
}