Skip to content

Commit

Permalink
modify circle buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Hiram committed Apr 4, 2019
1 parent d503625 commit b62d7e9
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 44 deletions.
180 changes: 140 additions & 40 deletions HiFramework/HiFramework/Extensions/CircleBuffer/CircleBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@

namespace HiFramework
{
public class CircullarBuffer<T> : ICircullarBuffer<T>
/// <summary>
/// This is a circular buffer class for reuse memory
/// </summary>
/// <typeparam name="T"></typeparam>
public class CircularBuffer<T> : ICircularBuffer<T>
{
/// <summary>
/// Read and write state
Expand All @@ -17,6 +21,7 @@ public enum State
{
WriteAhead,
ReadAhead,
WriteEqualRead, //init or read all data
}

/// <summary>
Expand All @@ -34,16 +39,23 @@ public enum State
/// </summary>
public State EState
{
get { return WritePosition >= ReadPosition ? State.WriteAhead : State.ReadAhead; }
get
{
if (WritePosition > ReadPosition)
return State.WriteAhead;
if (WritePosition < ReadPosition)
return State.ReadAhead;
return State.WriteEqualRead;
}
}

/// <summary>
/// Index of read position
/// Index of read position(this index is wait to read)
/// </summary>
public int ReadPosition { get; private set; }

/// <summary>
/// Index of write postion
/// Index of write postion(this index is wait to write)
/// </summary>
public int WritePosition { get; private set; }

Expand All @@ -63,6 +75,10 @@ public int HowManyCanWrite
{
remain = ReadPosition - WritePosition;
}
else if (EState == State.WriteEqualRead)
{
remain = Size;
}
return remain;
}
}
Expand All @@ -83,11 +99,15 @@ public int HowManyCanRead
{
remain = (Size - ReadPosition) + WritePosition;
}
else if (EState == State.WriteEqualRead)
{
remain = 0;
}
return remain;
}
}

public CircullarBuffer(int size = 2 << 13)
public CircularBuffer(int size = 2 << 13)
{
Size = size;
Array = new T[Size];
Expand All @@ -99,16 +119,12 @@ public CircullarBuffer(int size = 2 << 13)
/// <param name="length"></param>
public void MoveReadPosition(int length)
{
if (length > Size)
{
throw new Exception("Length is large than array's capacity");
}
if (length > HowManyCanRead)
{
throw new Exception("Read length large than data's length");
throw new ArgumentOutOfRangeException("Read length large than data's length");
}
var index = ReadPosition + length;
if (index > Size)
if (index >= Size)
{
index -= Size;
}
Expand All @@ -121,16 +137,12 @@ public void MoveReadPosition(int length)
/// <param name="length"></param>
public void MoveWritePosition(int length)
{
if (length > Size)
{
throw new Exception("Length is large than array's capacity");
}
if (length > HowManyCanWrite)
{
throw new Exception("Write length large than space");
}
var index = WritePosition + length;
if (index > Size)
if (index >= Size)
{
index -= Size;
}
Expand All @@ -147,57 +159,145 @@ public void Write(T[] array)
{
throw new Exception("Can not write so many data to array");
}
var length = Size - WritePosition;
if (length >= array.Length)//write into end

if (EState == State.WriteAhead)
{
var length = Size - WritePosition;
if (length >= array.Length) //write into end
{
for (int i = 0; i < array.Length; i++)
{
Array[WritePosition + i] = array[i];
}
}
else
{
int arrayIndex = 0;
for (int i = WritePosition; i < Size; i++) //write into end
{
Array[WritePosition + arrayIndex] = array[arrayIndex];
arrayIndex++;
}
var howManyAlreadWrite = arrayIndex; //alreay run arrayIndex++ so don't need +1
for (int i = 0; i < array.Length - howManyAlreadWrite; i++) //write into head
{
Array[i] = array[howManyAlreadWrite + i];
arrayIndex++;
}
}
}
else if (EState == State.ReadAhead)
{
for (int i = 0; i < array.Length; i++)
{
Array[WritePosition + i] = array[i];
}
}
else
else if (EState == State.WriteEqualRead)
{
for (int i = WritePosition; i < Size; i++)//write into end
var length = Size - WritePosition;
if (length >= array.Length) //write into end
{
Array[WritePosition + i] = array[i];
for (int i = 0; i < array.Length; i++)
{
Array[WritePosition + i] = array[i];
}
}
var howManyAlreadWrite = Size - WritePosition;
for (int i = 0; i < array.Length - howManyAlreadWrite; i++)//write into head
else
{
Array[i] = array[howManyAlreadWrite + i];
int arrayIndex = 0;
for (int i = WritePosition; i < Size; i++) //write into end
{
Array[i] = array[arrayIndex];
arrayIndex++;
}
var howManyAlreadWrite = arrayIndex; //alreay run arrayIndex++ so don't need +1
for (int i = 0; i < array.Length - howManyAlreadWrite; i++) //write into head
{
Array[i] = array[howManyAlreadWrite + i];
arrayIndex++;
}
}
}
else
{
throw new Exception("Write error");
}
MoveWritePosition(array.Length);
}

/// <summary>
/// Read all from array
/// </summary>
/// <returns></returns>
public T[] Read()
public T[] Read(int length)
{
T[] ts = new T[HowManyCanRead];
if (length > HowManyCanRead)
{
throw new Exception("Can not read so many data from array");
}
T[] array = new T[length];
if (EState == State.WriteAhead)
{
for (int i = 0; i < HowManyCanRead; i++)//read end
for (int i = 0; i < length; i++)
{
ts[i] = Array[ReadPosition + i];
array[i] = Array[ReadPosition + i];
}
}
else if (EState == State.ReadAhead)
{
var length = Size - ReadPosition;
for (int i = 0; i < length; i++)//read end
var remainLength = Size - ReadPosition;
if (remainLength >= length)
{
ts[i] = Array[ReadPosition + i];
for (int i = 0; i < length; i++)
{
array[i] = Array[ReadPosition + i];
}
}
for (int i = 0; i < WritePosition; i++)//read head
else
{
ts[length + i] = Array[i];
int arrayIndex = 0;
for (int i = ReadPosition; i < Size; i++)
{
array[arrayIndex] = Array[i];
arrayIndex++;
}
var howManyAlreadRead = arrayIndex; //alreay run arrayIndex++ so don't need +1
for (int i = 0; i < length - howManyAlreadRead; i++)
{
array[howManyAlreadRead + i] = Array[i];
arrayIndex++;
}
}
}
MoveReadPosition(ts.Length);
return ts;
else if (EState == State.WriteEqualRead) //write index back to read index
{
var remainLength = Size - ReadPosition;
if (remainLength >= length)
{
for (int i = 0; i < length; i++)
{
array[i] = Array[ReadPosition + i];
}
}
else
{
int arrayIndex = 0;
for (int i = ReadPosition; i < Size; i++)
{
array[arrayIndex] = Array[i];
arrayIndex++;
}
var howManyAlreadRead = arrayIndex; //alreay run arrayIndex++ so don't need +1
for (int i = 0; i < length - howManyAlreadRead; i++)
{
array[howManyAlreadRead + i] = Array[i];
arrayIndex++;
}
}
}
else
{
throw new Exception("read error");
}
MoveReadPosition(length);
return array;
}

/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
Expand All @@ -206,4 +306,4 @@ public void Dispose()
Array = null;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace HiFramework
/// Reuse array
/// </summary>
/// <typeparam name="T"></typeparam>
interface ICircullarBuffer<T> : IDisposable
public interface ICircularBuffer<T> : IDisposable
{
/// <summary>
/// Array to contain element
Expand All @@ -27,7 +27,7 @@ interface ICircullarBuffer<T> : IDisposable
/// <summary>
/// Current read and write state
/// </summary>
CircullarBuffer<T>.State EState { get; }
CircularBuffer<T>.State EState { get; }

/// <summary>
/// Index of read position
Expand Down Expand Up @@ -68,9 +68,10 @@ interface ICircullarBuffer<T> : IDisposable
void Write(T[] bytes);

/// <summary>
/// Read all from array
/// How many data to read
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
T[] Read();
T[] Read(int length);
}
}
Binary file modified unity/Assets/HiFramework/HiFramework.dll
Binary file not shown.

0 comments on commit b62d7e9

Please sign in to comment.