W
William Stacey
Working with implementing a circular buffer for a producer/consumer deal.
Have not done one in a while. The following seems to work. However, I
remember and have seen other implementation that make the buffer 1 more then
the needed capacity so that a full buffer and an empty buffer can be
differentiated. However this implementation does not do that (i.e. the
capacity and the buffer size is the same.) I assume the following does not
need the extra buffer element because I am always tracking "used" (where the
other implementation would not do that as you could calculate that with the
readPos/writePos markers.) Just wondering if this imp. will somehow break
down for certain things or what the pros or cons are between the two
implementations (this seems a bit more straight forward)? TIA
//no locking yet.
public class CircularBuffer
{
private object[] buffer;
public int readPos;
public int writePos;
public int used;
public int size;
public CircularBuffer(int size)
{
this.size = size;
buffer = new object[size];
readPos = 0;
writePos = 0;
used = 0;
}
public void Put(object o)
{
if (IsFull())
throw new ApplicationException("Buffer is Full.");
buffer[writePos] = o;
writePos = (writePos + 1) % size;
used++;
}
public object Get()
{
if (IsEmpty())
throw new ApplicationException("Buffer is Empty.");
object o = buffer[readPos];
readPos = (readPos + 1) % size;
used--;
return o;
}
public bool IsFull()
{
return (used == size);
}
public bool IsEmpty()
{
return (used == 0);
}
public int Free
{
get { return size - used; }
}
} // End Class
Have not done one in a while. The following seems to work. However, I
remember and have seen other implementation that make the buffer 1 more then
the needed capacity so that a full buffer and an empty buffer can be
differentiated. However this implementation does not do that (i.e. the
capacity and the buffer size is the same.) I assume the following does not
need the extra buffer element because I am always tracking "used" (where the
other implementation would not do that as you could calculate that with the
readPos/writePos markers.) Just wondering if this imp. will somehow break
down for certain things or what the pros or cons are between the two
implementations (this seems a bit more straight forward)? TIA
//no locking yet.
public class CircularBuffer
{
private object[] buffer;
public int readPos;
public int writePos;
public int used;
public int size;
public CircularBuffer(int size)
{
this.size = size;
buffer = new object[size];
readPos = 0;
writePos = 0;
used = 0;
}
public void Put(object o)
{
if (IsFull())
throw new ApplicationException("Buffer is Full.");
buffer[writePos] = o;
writePos = (writePos + 1) % size;
used++;
}
public object Get()
{
if (IsEmpty())
throw new ApplicationException("Buffer is Empty.");
object o = buffer[readPos];
readPos = (readPos + 1) % size;
used--;
return o;
}
public bool IsFull()
{
return (used == size);
}
public bool IsEmpty()
{
return (used == 0);
}
public int Free
{
get { return size - used; }
}
} // End Class