Created
July 24, 2013 11:27
-
-
Save 0x53A/6069766 to your computer and use it in GitHub Desktop.
Ringbuffer in C#, fixed size
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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