Skip to content

Instantly share code, notes, and snippets.

@0x53A
Created July 24, 2013 11:27
Show Gist options
  • Save 0x53A/6069766 to your computer and use it in GitHub Desktop.
Save 0x53A/6069766 to your computer and use it in GitHub Desktop.
Ringbuffer in C#, fixed size
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
namespace xxx
{
public class RingBuffer<T>
{
protected T[] _buffer;
protected int _nReadNext;
protected int _nWriteNext;
protected int _nAvailable;
private object _lock;
public int Size { get; private set; }
public int Available { get { return _nAvailable; } }
public int Free { get { return Size - _nAvailable; } }
public RingBuffer(int size)
{
Size = size;
_buffer = new T[size];
_nAvailable = 0;
_nReadNext = 0;
_nWriteNext = 0;
_lock = new object();
}
public void Clear()
{
lock (_lock)
{
_nReadNext = 0;
_nWriteNext = 0;
_nAvailable = 0;
}
}
public void Seek(int count)
{
lock (_lock)
{
if (count > _nAvailable)
throw new Exception("underflow");
_nReadNext += count;
_nReadNext %= Size;
_nAvailable -= count;
}
}
public void Peek(T[] data, int offset, int count)
{
lock (_lock)
{
if (_nAvailable < count)
throw new Exception("underflow");
if (count <= (Size - _nReadNext))
{
Array.Copy(_buffer, _nReadNext, data, offset, count);
}
else
{
int copyOnFirst = Size - _nReadNext;
int copyOnSecond = count - copyOnFirst;
Array.Copy(_buffer, _nReadNext, data, offset, copyOnFirst);
Array.Copy(_buffer, 0, data, offset + copyOnFirst, copyOnSecond);
}
}
}
public T Peek()
{
lock (_lock)
{
if (_nAvailable < 1)
throw new Exception("underflow");
return _buffer[_nReadNext];
}
}
public T Peek(int offset)
{
lock (_lock)
{
if (_nAvailable <= offset)
throw new Exception("underflow");
offset = _nReadNext + offset;
offset = offset % Size;
return _buffer[offset];
}
}
public T[] Peek(int offset, int count)
{
lock (_lock)
{
if (_nAvailable <= (count + offset))
throw new Exception("underflow");
T[] data = new T[count];
if (count <= (Size - _nReadNext))
{
Array.Copy(_buffer, _nReadNext, data, offset, count);
}
else
{
int copyOnFirst = Size - _nReadNext;
int copyOnSecond = count - copyOnFirst;
Array.Copy(_buffer, _nReadNext, data, offset, copyOnFirst);
Array.Copy(_buffer, 0, data, offset + copyOnFirst, copyOnSecond);
}
return data;
}
}
public void Read(T[] data, int offset, int count)
{
lock (_lock)
{
if (_nAvailable < count)
throw new Exception("underflow");
if (count <= (Size - _nReadNext))
{
Array.Copy(_buffer, _nReadNext, data, offset, count);
_nReadNext += count;
_nAvailable -= count;
}
else
{
int copyOnFirst = Size - _nReadNext;
int copyOnSecond = count - copyOnFirst;
Array.Copy(_buffer, _nReadNext, data, offset, copyOnFirst);
Array.Copy(_buffer, 0, data, offset + copyOnFirst, copyOnSecond);
_nAvailable -= count;
_nReadNext = copyOnSecond;
}
}
}
public T[] Read(int offset, int count)
{
T[] buff = new T[count];
Read(buff, offset, count);
return buff;
}
public T[] Read(int count)
{
return Read(0, count);
}
public void Write(T data)
{
lock (_lock)
{
if (Free < 1)
throw new Exception("overflow");
_buffer[_nWriteNext] = data;
_nWriteNext++;
_nWriteNext %= Size;
_nAvailable += 1;
}
}
public void Write(T[] data)
{
Write(data, 0, data.Length);
}
public void Write(T[] data, int offset, int count)
{
lock (_lock)
{
if (Free < count)
throw new Exception("overflow");
if (count <= (Size - _nWriteNext))
{
Array.Copy(data, offset, _buffer, _nWriteNext, count);
_nWriteNext += count;
_nAvailable += count;
}
else
{
int copyOnFirst = Size - _nWriteNext;
int copyOnSecond = count - copyOnFirst;
Array.Copy(data, offset, _buffer, _nWriteNext, copyOnFirst);
Array.Copy(data, offset + copyOnFirst, _buffer, 0, copyOnSecond);
_nAvailable += count;
_nWriteNext = copyOnSecond;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment