73 lines
1.8 KiB
C#
73 lines
1.8 KiB
C#
|
using System.Threading;
|
|||
|
|
|||
|
public class RingBuffer<T>
|
|||
|
{
|
|||
|
private readonly T[] buffer;
|
|||
|
private readonly int capacity;
|
|||
|
private int writePos;
|
|||
|
private int readPos;
|
|||
|
private int count;
|
|||
|
|
|||
|
public RingBuffer(int capacity)
|
|||
|
{
|
|||
|
this.capacity = capacity;
|
|||
|
this.buffer = new T[capacity];
|
|||
|
this.writePos = 0;
|
|||
|
this.readPos = 0;
|
|||
|
this.count = 0;
|
|||
|
}
|
|||
|
|
|||
|
public void Write(T item)
|
|||
|
{
|
|||
|
int localWritePos;
|
|||
|
int localReadPos;
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
localWritePos = Volatile.Read(ref writePos);
|
|||
|
localReadPos = Volatile.Read(ref readPos);
|
|||
|
|
|||
|
int nextWritePos = (localWritePos + 1) % capacity;
|
|||
|
|
|||
|
if (nextWritePos == localReadPos)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos);
|
|||
|
}
|
|||
|
}
|
|||
|
while (Interlocked.CompareExchange(ref writePos, (localWritePos + 1) % capacity, localWritePos) != localWritePos);
|
|||
|
|
|||
|
buffer[localWritePos] = item;
|
|||
|
Interlocked.Increment(ref count);
|
|||
|
}
|
|||
|
|
|||
|
public bool TryRead(out T item)
|
|||
|
{
|
|||
|
item = default(T);
|
|||
|
|
|||
|
int localReadPos;
|
|||
|
int localWritePos;
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
localReadPos = Volatile.Read(ref readPos);
|
|||
|
localWritePos = Volatile.Read(ref writePos);
|
|||
|
|
|||
|
if (localReadPos == localWritePos)
|
|||
|
{
|
|||
|
return false; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
|
|||
|
}
|
|||
|
}
|
|||
|
while (Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos) != localReadPos);
|
|||
|
|
|||
|
item = buffer[localReadPos];
|
|||
|
Interlocked.Decrement(ref count);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public int Available()
|
|||
|
{
|
|||
|
return Volatile.Read(ref count);
|
|||
|
}
|
|||
|
}
|