Click here to Skip to main content
15,881,424 members
Articles / Programming Languages / C#

Circular Buffer

Rate me:
Please Sign up or sign in to vote.
4.50/5 (20 votes)
11 Sep 20023 min read 245.5K   10.3K   84  
C# implementation of a Circular Buffer
<?xml version="1.0"?>
<doc>
    <assembly>
        <name>CircularBuffer</name>
    </assembly>
    <members>
        <member name="T:CircularBuffer.QueueCB">
            <summary>
            Summary description for CircularBuffer.
            <newpara>Implements a <b>Circular Buffer</b>. </newpara>
            The Circular Buffer is a memory queue where memory locations
            are reused when the data producer (writer) overwrites (modulo
            the buffer size) previously used locations.
            The Circular Buffer operates in two modes of operation: the
            synchronous mode and the asychronous mode. The synchronous mode is 
            useful where one process, either the producer (writer) or the consumer
            (reader), operates much faster than the other. The faster process 
            would otherwise waste time waiting for the slower process. 
            Instead the faster process can "burst" off the data into the 
            Circular Buffer and continue. The slower process will read the 
            data at its own rate. However, in the synchronous mode,
            the producer and consumer of the Circular Buffer must access the queue 
            at the same average rate over time or an overflow or underflow of 
            data will occur.
            In the asychronous mode, we are only interested in the last data 
            items written by the producer--earlier data will be lost. This is useful 
            in debug tracing where debug information is continuously written into 
            the Circular Buffer over a period of time until the error 
            condition is detected. The Circular Buffer is then examined for the 
            sequence of states, commands, etc. written just before the error 
            was detected to help isolate the bug. 
            The actual capacity of the Circular Buffer is one less (N-1) than the
            total length of the Buffer(N) so that a full buffer and an empty 
            buffer can be differentianted. The default length is N=256 for a 
            default capacity of 255.
            A client process can be notified that the Circular Buffer has reached
            a specified count (WaterMark) using the CBEventHandler delegate
            <newpara>
            // Example 
            </newpara>
            <newpara>
             <code>
            theCB.SetWaterMark(8); // notify every time cb is at count 8 
             </code>
            </newpara>
            <newpara>
             <code>
            theCB.WaterMarkNotify += new QueueCB.CBEventHandler(OnWaterMarkEvent);
             </code>
            </newpara>
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.#ctor">
            <summary>
            Default Constructor creates N=256 element
            Circular Buffer.
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.#ctor(System.Object)">
            <summary>
            Constructor creates N=256 element 
            Circular Buffer with type specified
            </summary>
            <c>QueueCB theCB = new QueueCB(typeof(string));</c>
            <param name="o">Generic Object</param>
        </member>
        <member name="M:CircularBuffer.QueueCB.#ctor(System.Object,System.Int32)">
            <summary>
            Constructor creates N=len element 
            Circular Buffer with type specified
            </summary>
            <param name="o">Generic Object</param>
            <param name="len">Circular Buffer Length (# of elements)</param>
        </member>
        <member name="M:CircularBuffer.QueueCB.#ctor(System.Int32)">
            <summary>
            Constructor creates N=len element 
            Circular Buffer with type unspecified
            </summary>
            <param name="len">Circular Buffer Length (# of elements)</param>
        </member>
        <member name="M:CircularBuffer.QueueCB.Clear">
            <summary>
            Clears the Circular Buffer and initializes with null
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.WaterMarkEnable">
            <summary>
            Enable WaterMark (queue count) checking
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.WaterMarkDisable">
            <summary>
            Disable WaterMark (queue count) checking
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.SetAsynchronousMode">
            <summary>
            Sets Asynchronous Mode of Circular Buffer operation--
            see class summary
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.SetSynchronousMode">
            <summary>
            Sets Synchronous Mode of Circular Buffer operation--
            see class summary
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.SetWaterMark(System.Int32)">
            <summary>
            Sets WaterMark (queue count) value for
            WaterMark event operations
            </summary>
            <param name="mark">Positive Integer WaterMark event value</param>
        </member>
        <member name="M:CircularBuffer.QueueCB.Peek">
            <summary>
            Returns item at read index without modifing the queue
            <exception> throws exception if queue empty</exception>
            </summary>
            <returns>Returns the object at the read index 
            <c>without</c> removing it (modifing the index)</returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.Enqueue(System.Object)">
            <summary>
            Add single item to the Circular Buffer
            </summary>
            <param name="o">Generic Object </param>
        </member>
        <member name="M:CircularBuffer.QueueCB.Enqueue(System.Array)">
            <summary>
            Add entire Array[] to the Circular Buffer
            </summary>
            <param name="a">Array[]</param>
        </member>
        <member name="M:CircularBuffer.QueueCB.EnqueueBlocking(System.Object)">
            <summary>
            Add a single item to the Circular Buffer but block if no room.
            Used with synchronous mode only.
            </summary>
            <param name="o">Generic Object</param>
        </member>
        <member name="M:CircularBuffer.QueueCB.EnqueueBlocking(System.Array)">
            <summary>
            Add entire Array[] to the Circular Buffer but block if no room.
            Used with synchronous mode only.
            </summary>
            <param name="a">Array[]</param>
        </member>
        <member name="M:CircularBuffer.QueueCB.Dequeue">
            <summary>
            Return/Remove single item from the Circular Buffer
            Will throw exception if no items are in the Circular Buffer 
            regardless of mode.
            This and CopyTo(Array, index, number) are the only queue 
            item removal methods that will check for underflow and throw an 
            exception. Others will either block or return the number 
            of items they were able to successfully remove.
            </summary>
            <returns>returns/removes a single object from the 
            Circular Buffer</returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.DequeueBlocking">
            <summary>
            Return/Remove single item from the Circular Buffer but block
            if empty. Must be in synchronous mode.
            </summary>
            <returns>returns/removes a single object from the
            Circular Buffer</returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.CopyTo(System.Array,System.Int32)">
            <summary>
            Copy/Remove items from entire Circular Buffer to an Array[] 
            with Array offset of index.
            </summary>
            <param name="a">Target Array[]</param>
            <param name="index">Target Array[] offset</param>
            <returns>Number of items copied/removed from Circular Buffer
            </returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.CopyTo(System.Array,System.Int32,System.Int32)">
            <summary>
            Copy/Remove num items from Circular Buffer to an Array[] 
            with Array offset of index.
            This and Dequeue() are the only queue 
            item removal methods that will check for underflow and throw an 
            exception. Others will either block or return the number 
            of items they were able to successfully remove.
            </summary>
            <param name="a">Target Array[]</param>
            <param name="index">Target Array[] offset</param>
            <param name="num">Number of items to copy/remove</param>
            <returns>Number of items copied/removed from Circular Buffer
            </returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.CopyTo(System.Array)">
            <summary>
            Copy/Remove items from entire Circular Buffer to an Array[]
            </summary>
            <param name="a">Target Array[]</param>
            <returns>Number if items copied/removed from Circular Buffer
            </returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.CopyToBlocking(System.Array,System.Int32)">
            <summary>
            Copy/Remove items from entire Circular Buffer to an Array[] 
            with Array offset of index but block if empty. Must be in
            synchronous mode.
            </summary>
            <param name="a">Target Array[]</param>
            <param name="index">Target Array[] offset</param>
            <returns>Number if items copied/removed from Circular Buffer
            </returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.CopyToBlocking(System.Array,System.Int32,System.Int32)">
            <summary>
            Copy/Remove items from entire Circular Buffer to an Array[] 
            with Array offset of index but block if empty. Must be in
            synchronous mode.
            </summary>
            <param name="a">Target Array[]</param>
            <param name="index">Target Array[] offset</param>
            <param name="numbertocopy">number to copy</param>
            <returns>Number if items copied/removed from Circular Buffer
            </returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.CopyToBlocking(System.Array)">
            <summary>
            Copy/Remove items from entire Circular Buffer to an Array[] 
            with Array offset of zero but block if empty. Must be in
            synchronous mode.
            </summary>
            <param name="a">Target Array[]</param>
            <returns>Number if items copied/removed from Circular Buffer
            </returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.DumpCircularBuffer">
            <summary>
            Displays Circular Buffer contents and or state information.
            Overridable.
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.OnWaterMarkNotify">
            <summary>
            Raise the watermark event by invoking the delegates
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.GetEnumerator">
            <summary>
            IEnumerator support
            </summary>
            <returns></returns>
        </member>
        <member name="E:CircularBuffer.QueueCB.WaterMarkNotify">
            <summary>
            WaterMark event
            </summary>
        </member>
        <member name="P:CircularBuffer.QueueCB.Count">
            <summary>
            Returns current number of items in the Circular Buffer.
            In the asynchronous mode, count will staturate at N-1 if an 
            overflow conditions exists. The read index will then follow the 
            write index so that the lastest items are always available.
            </summary>
        </member>
        <member name="P:CircularBuffer.QueueCB.ReadIndex">
            <summary>
            Returns next Read Index
            </summary>
        </member>
        <member name="P:CircularBuffer.QueueCB.WriteIndex">
            <summary>
            Returns next Write Index
            </summary>
        </member>
        <member name="P:CircularBuffer.QueueCB.Synchronousmode">
            <remarks>
            1> Synchronous Mode -- In the synchronous mode the emptying of the 
            Circular Buffer must occur at the same average rate as the filling 
            of the Circular Buffer so that the overrun condition never occurs. 
            That is, as the tail index chases the head index around the circle 
            of the buffer, the head index always stays ahead (in a modulo N sense)
            of the tail index. No data is lost. An exception will be thrown when 
            a buffer overrun condition occurs.
            <newpara>
            2> Asynchronous Mode -- In the asynchronous mode, data will be lost 
            as the Circular Buffer is overwritten. Usually in this mode, only 
            the last item written are of interest. When the Write index 
            (head index) catches the Read Index (tail index) the Read Index is 
            automatically incremented and the Circular Buffer count will indicate 
            N-1 items in the Buffer.
            The synchronous mode is pretty straight forward as most of the 
            responsibility for avoiding buffer overflow is a system issue for the 
            producer and consumer of the data. The circular buffer just checks 
            for error conditions.
            The asynchronous mode is more difficult as buffer overruns are allowed.
            So things operate as normal until the maximum occupancy is reached in 
            the asynchronous mode. From then on, while the buffer is still at 
            maximum occupancy, the read index follows the write index. This 
            simulates synchronous operation. I call this the saturation
            mode. While saturation exists, an additional complication must be 
            handled when the data is read. The read index is stored ahead of valid 
            data (write index so an adjustment must be made before it is used to 
            output data from the circular buffer. 
            Capacity is N-1
            </newpara>
            </remarks>		
            <summary>
            Used to set synchronous or asynchronous modes of operation
            Modes differ in how they handle the buffer overflow 
            condition.
            </summary>
            <value>Property <c>Synchronousmode</c>set to true of false</value>
        </member>
        <member name="P:CircularBuffer.QueueCB.Watermark">
            <summary>
            Sets the level (queue count) at which the WaterMarkNotify event
            will fire. 
            </summary>
            <value>Property <c>Watermark</c>Pos. integer at which event fires</value>
        </member>
        <member name="P:CircularBuffer.QueueCB.Watermarkflag">
            <summary>
            Enables WaterMark checking
            </summary>
            <value>Property <c>Watermarkflag</c>bool enables watermark checking when true</value>
        </member>
        <member name="P:CircularBuffer.QueueCB.GetVersion">
            <summary>
            Returns assembly version string
            </summary>
            <return>Version string "n.n.n.n"</return>
        </member>
        <member name="T:CircularBuffer.QueueCB.CBEventHandler">
            <summary>
            Delegate for the WaterMark event.
            </summary>
        </member>
        <member name="T:CircularBuffer.QueueCB.CBEnumerator">
            <summary>
            A helper class
            </summary>
        </member>
        <member name="M:CircularBuffer.QueueCB.CBEnumerator.MoveNext">
            <summary>
            IEnumerator support
            </summary>
            <returns></returns>
        </member>
        <member name="M:CircularBuffer.QueueCB.CBEnumerator.Reset">
            <summary>
            IEnumerator support
            </summary>
        </member>
        <member name="P:CircularBuffer.QueueCB.CBEnumerator.Current">
            <summary>
            IEnumerator support
            </summary>
        </member>
    </members>
</doc>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions