Deque implemented using a circular array

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












I found a tutorial on implementing a deque using a circular array. I changed the implementation but I am not sure if it is correct or not.



So I have one question:



  1. I wrote code that uses an addCount field to record whether there are any additions, but I'm not sure if it's correct? If not, please tell me where I made an error.


class Deque 
static final int MAX = 100;
int arr;
int front;
int rear;
int size;
int addCount;

public Deque(int size)
arr = new int[size];
front = 0;
rear = 0;
this.size = size;
addCount = 0;


// Checks whether Deque is full or not.
boolean isFull()

return front == rear && !isEmpty();


// Checks whether Deque is empty or not.
boolean isEmpty()
return front == rear && addCount == 0;


// Inserts an element at front
void insertfront(int key)
if (isFull())
return;

addCount++;
arr[front] = key;
front = front + 1;
front %= this.size;


// function to inset element at rear end
// of Deque.
void insertrear(int key)
if (isFull())
return;
addCount++;
rear = (rear - 1) % this.size;
arr[rear + this.size] = key;



// Deletes element at front end of Deque
void deletefront()
if (isEmpty())
return;
addCount--;
front = (front - 1) % this.size;


// Delete element at rear end of Deque
void deleterear()
if (isEmpty())
return;
addCount--;
rear = (rear + 1) % this.size;


// Returns front element of Deque
int getFront()
int getFront = front-1;

if (getFront < 0)
getFront += this.size;
return arr[getFront % this.size];


// function return rear element of Deque
int getRear()
int getRearIndex = rear + this.size;
return arr[getRearIndex % this.size];


// Driver program to test above function
public static void main(String args)
Deque dq = new Deque(5);
System.out.println("Insert element at rear end : 5 ");
dq.insertrear(5);

System.out.println("insert element at rear end : 10 ");
dq.insertrear(10);

System.out.println("get rear element : " + dq.getRear());

dq.deleterear();
System.out.println("After delete rear element new rear become : " + dq.getRear());

System.out.println("inserting element at front end");
dq.insertfront(15);

System.out.println("get front element: " + dq.getFront());

dq.deletefront();

System.out.println("After delete front element new front become : " + +dq.getFront());









share|improve this question





















  • What's magic about start=-1?
    – Oscar Smith
    Feb 7 at 3:01










  • I thinks is subjective. It's not important here, I will delete it. thanks.
    – beehuang
    Feb 7 at 3:02
















up vote
1
down vote

favorite












I found a tutorial on implementing a deque using a circular array. I changed the implementation but I am not sure if it is correct or not.



So I have one question:



  1. I wrote code that uses an addCount field to record whether there are any additions, but I'm not sure if it's correct? If not, please tell me where I made an error.


class Deque 
static final int MAX = 100;
int arr;
int front;
int rear;
int size;
int addCount;

public Deque(int size)
arr = new int[size];
front = 0;
rear = 0;
this.size = size;
addCount = 0;


// Checks whether Deque is full or not.
boolean isFull()

return front == rear && !isEmpty();


// Checks whether Deque is empty or not.
boolean isEmpty()
return front == rear && addCount == 0;


// Inserts an element at front
void insertfront(int key)
if (isFull())
return;

addCount++;
arr[front] = key;
front = front + 1;
front %= this.size;


// function to inset element at rear end
// of Deque.
void insertrear(int key)
if (isFull())
return;
addCount++;
rear = (rear - 1) % this.size;
arr[rear + this.size] = key;



// Deletes element at front end of Deque
void deletefront()
if (isEmpty())
return;
addCount--;
front = (front - 1) % this.size;


// Delete element at rear end of Deque
void deleterear()
if (isEmpty())
return;
addCount--;
rear = (rear + 1) % this.size;


// Returns front element of Deque
int getFront()
int getFront = front-1;

if (getFront < 0)
getFront += this.size;
return arr[getFront % this.size];


// function return rear element of Deque
int getRear()
int getRearIndex = rear + this.size;
return arr[getRearIndex % this.size];


// Driver program to test above function
public static void main(String args)
Deque dq = new Deque(5);
System.out.println("Insert element at rear end : 5 ");
dq.insertrear(5);

System.out.println("insert element at rear end : 10 ");
dq.insertrear(10);

System.out.println("get rear element : " + dq.getRear());

dq.deleterear();
System.out.println("After delete rear element new rear become : " + dq.getRear());

System.out.println("inserting element at front end");
dq.insertfront(15);

System.out.println("get front element: " + dq.getFront());

dq.deletefront();

System.out.println("After delete front element new front become : " + +dq.getFront());









share|improve this question





















  • What's magic about start=-1?
    – Oscar Smith
    Feb 7 at 3:01










  • I thinks is subjective. It's not important here, I will delete it. thanks.
    – beehuang
    Feb 7 at 3:02












up vote
1
down vote

favorite









up vote
1
down vote

favorite











I found a tutorial on implementing a deque using a circular array. I changed the implementation but I am not sure if it is correct or not.



So I have one question:



  1. I wrote code that uses an addCount field to record whether there are any additions, but I'm not sure if it's correct? If not, please tell me where I made an error.


class Deque 
static final int MAX = 100;
int arr;
int front;
int rear;
int size;
int addCount;

public Deque(int size)
arr = new int[size];
front = 0;
rear = 0;
this.size = size;
addCount = 0;


// Checks whether Deque is full or not.
boolean isFull()

return front == rear && !isEmpty();


// Checks whether Deque is empty or not.
boolean isEmpty()
return front == rear && addCount == 0;


// Inserts an element at front
void insertfront(int key)
if (isFull())
return;

addCount++;
arr[front] = key;
front = front + 1;
front %= this.size;


// function to inset element at rear end
// of Deque.
void insertrear(int key)
if (isFull())
return;
addCount++;
rear = (rear - 1) % this.size;
arr[rear + this.size] = key;



// Deletes element at front end of Deque
void deletefront()
if (isEmpty())
return;
addCount--;
front = (front - 1) % this.size;


// Delete element at rear end of Deque
void deleterear()
if (isEmpty())
return;
addCount--;
rear = (rear + 1) % this.size;


// Returns front element of Deque
int getFront()
int getFront = front-1;

if (getFront < 0)
getFront += this.size;
return arr[getFront % this.size];


// function return rear element of Deque
int getRear()
int getRearIndex = rear + this.size;
return arr[getRearIndex % this.size];


// Driver program to test above function
public static void main(String args)
Deque dq = new Deque(5);
System.out.println("Insert element at rear end : 5 ");
dq.insertrear(5);

System.out.println("insert element at rear end : 10 ");
dq.insertrear(10);

System.out.println("get rear element : " + dq.getRear());

dq.deleterear();
System.out.println("After delete rear element new rear become : " + dq.getRear());

System.out.println("inserting element at front end");
dq.insertfront(15);

System.out.println("get front element: " + dq.getFront());

dq.deletefront();

System.out.println("After delete front element new front become : " + +dq.getFront());









share|improve this question













I found a tutorial on implementing a deque using a circular array. I changed the implementation but I am not sure if it is correct or not.



So I have one question:



  1. I wrote code that uses an addCount field to record whether there are any additions, but I'm not sure if it's correct? If not, please tell me where I made an error.


class Deque 
static final int MAX = 100;
int arr;
int front;
int rear;
int size;
int addCount;

public Deque(int size)
arr = new int[size];
front = 0;
rear = 0;
this.size = size;
addCount = 0;


// Checks whether Deque is full or not.
boolean isFull()

return front == rear && !isEmpty();


// Checks whether Deque is empty or not.
boolean isEmpty()
return front == rear && addCount == 0;


// Inserts an element at front
void insertfront(int key)
if (isFull())
return;

addCount++;
arr[front] = key;
front = front + 1;
front %= this.size;


// function to inset element at rear end
// of Deque.
void insertrear(int key)
if (isFull())
return;
addCount++;
rear = (rear - 1) % this.size;
arr[rear + this.size] = key;



// Deletes element at front end of Deque
void deletefront()
if (isEmpty())
return;
addCount--;
front = (front - 1) % this.size;


// Delete element at rear end of Deque
void deleterear()
if (isEmpty())
return;
addCount--;
rear = (rear + 1) % this.size;


// Returns front element of Deque
int getFront()
int getFront = front-1;

if (getFront < 0)
getFront += this.size;
return arr[getFront % this.size];


// function return rear element of Deque
int getRear()
int getRearIndex = rear + this.size;
return arr[getRearIndex % this.size];


// Driver program to test above function
public static void main(String args)
Deque dq = new Deque(5);
System.out.println("Insert element at rear end : 5 ");
dq.insertrear(5);

System.out.println("insert element at rear end : 10 ");
dq.insertrear(10);

System.out.println("get rear element : " + dq.getRear());

dq.deleterear();
System.out.println("After delete rear element new rear become : " + dq.getRear());

System.out.println("inserting element at front end");
dq.insertfront(15);

System.out.println("get front element: " + dq.getFront());

dq.deletefront();

System.out.println("After delete front element new front become : " + +dq.getFront());











share|improve this question












share|improve this question




share|improve this question








edited Feb 7 at 10:47









Pieter Witvoet

3,611721




3,611721









asked Feb 7 at 2:58









beehuang

63




63











  • What's magic about start=-1?
    – Oscar Smith
    Feb 7 at 3:01










  • I thinks is subjective. It's not important here, I will delete it. thanks.
    – beehuang
    Feb 7 at 3:02
















  • What's magic about start=-1?
    – Oscar Smith
    Feb 7 at 3:01










  • I thinks is subjective. It's not important here, I will delete it. thanks.
    – beehuang
    Feb 7 at 3:02















What's magic about start=-1?
– Oscar Smith
Feb 7 at 3:01




What's magic about start=-1?
– Oscar Smith
Feb 7 at 3:01












I thinks is subjective. It's not important here, I will delete it. thanks.
– beehuang
Feb 7 at 3:02




I thinks is subjective. It's not important here, I will delete it. thanks.
– beehuang
Feb 7 at 3:02










3 Answers
3






active

oldest

votes

















up vote
2
down vote













I do not see any problems with addCount as long as we add a disclaimer that this solution is not thread safe.



The presented solution is a collection that can only accept int items. You can expand this if you add generic parameter to the class. Note that in this case, the internal array is of Object type and you let the compiler enforce type safety and also do auto-boxing to support primitive data items, just like in Java collections library. And while we mentioned that, you might want to consider making your solution implement the Deque interface from Java collections so that clients will work with a familiar API (of course you will want to change the name of the class to reflect that it is a concrete implementation of a Deque)






share|improve this answer






























    up vote
    1
    down vote













    Bugs



    If you call insertrear() and deletefront() repeatedly, you will eventually get an array out of bounds exception. There are at least two problems:



    This code in insertrear() can index past the end of the array:




     rear = (rear - 1) % this.size;
    arr[rear + this.size] = key;



    If the first statement results in rear being 0, the second statement will try to access an element out of bounds.



    This code in deletefront() can cause front to become negative:




     front = (front - 1) % this.size;



    which will cause the next addfront() call to throw an exception because it will try to use front as an array index without fixing it.



    I would recommend never letting front and rear go negative. First, this fixes your array bounds issues. Second, it also fixes an additional bug when you check front == rear and it should return true but it doesn't because one index is positive and one index is negative.



    Poor testing



    If you had exercised your code more, you would have caught these bugs. When writing tests for your code, you should make sure to stress it, not just do the bare minimum. For example, you should fill your queue to capacity and see what happens if you try to overfill it. You should also try every combination of filling from the front/rear with removing from the front/rear (4 separate tests at least).






    share|improve this answer






























      up vote
      0
      down vote













      With a circular buffer, you only need to keep track of two variables: writeIndex and itemCount.



      • Both items are incremented when you write an item to the buffer


      • itemCount is decremented when you read an item from the buffer

      • You calculate the read index by subtracting the itemCount from the writeIndex

      • You transition from the bottom of the buffer to the top by using modulus math

      Here are the details:



      Add data to the buffer:



      writeIndex = ((writeIndex + 1) % BUFFER_SIZE)
      if (itemCount < BUFFER_SIZE) itemCount++;
      write data to buffer[writeIndex]


      Remove data from the buffer:



      if (itemCount > 0) 
      readIndex = ((BUFFER_SIZE + writeIndex - itemCount + 1) % BUFFER_SIZE)
      read data from the buffer[readIndex]
      itemCount--;
      }


      Example:



      BUFFER_SIZE = 6
      writeIndex = 4
      itemCount = 3

      add item, new writeIndex = (4 + 1) % 6 = 5 % 6 = 5 new itemCount = 4
      add item, new writeIndex = (5 + 1) % 6 = 6 % 6 = 0 new itemCount = 5
      read item, new readIndex = (6+0-5+1) % 6 = 2%6 = 2 new itemCount = 4
      read item, new readIndex = (6+0-4+1) % 6 = 3%6 = 3 new itemCount = 3


      • % = modulus ... returns the remainder of a division

      • 5%6 = 5/6, remainder 5

      • 6%6 = 6/6, remainder 0

      This example allows the overwriting of unread data.



      Overwriting can be disabled by:



      if (itemCount<BUFFER_SIZE) write logic


      This example is not thread-safe. If you read and write in different threads, you'll need to add a locking mechanism to assure reading and writing operations do not occur at the same time.






      share|improve this answer























        Your Answer




        StackExchange.ifUsing("editor", function ()
        return StackExchange.using("mathjaxEditing", function ()
        StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
        StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
        );
        );
        , "mathjax-editing");

        StackExchange.ifUsing("editor", function ()
        StackExchange.using("externalEditor", function ()
        StackExchange.using("snippets", function ()
        StackExchange.snippets.init();
        );
        );
        , "code-snippets");

        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "196"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        convertImagesToLinks: false,
        noModals: false,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );








         

        draft saved


        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186964%2fdeque-implemented-using-a-circular-array%23new-answer', 'question_page');

        );

        Post as a guest






























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        2
        down vote













        I do not see any problems with addCount as long as we add a disclaimer that this solution is not thread safe.



        The presented solution is a collection that can only accept int items. You can expand this if you add generic parameter to the class. Note that in this case, the internal array is of Object type and you let the compiler enforce type safety and also do auto-boxing to support primitive data items, just like in Java collections library. And while we mentioned that, you might want to consider making your solution implement the Deque interface from Java collections so that clients will work with a familiar API (of course you will want to change the name of the class to reflect that it is a concrete implementation of a Deque)






        share|improve this answer



























          up vote
          2
          down vote













          I do not see any problems with addCount as long as we add a disclaimer that this solution is not thread safe.



          The presented solution is a collection that can only accept int items. You can expand this if you add generic parameter to the class. Note that in this case, the internal array is of Object type and you let the compiler enforce type safety and also do auto-boxing to support primitive data items, just like in Java collections library. And while we mentioned that, you might want to consider making your solution implement the Deque interface from Java collections so that clients will work with a familiar API (of course you will want to change the name of the class to reflect that it is a concrete implementation of a Deque)






          share|improve this answer

























            up vote
            2
            down vote










            up vote
            2
            down vote









            I do not see any problems with addCount as long as we add a disclaimer that this solution is not thread safe.



            The presented solution is a collection that can only accept int items. You can expand this if you add generic parameter to the class. Note that in this case, the internal array is of Object type and you let the compiler enforce type safety and also do auto-boxing to support primitive data items, just like in Java collections library. And while we mentioned that, you might want to consider making your solution implement the Deque interface from Java collections so that clients will work with a familiar API (of course you will want to change the name of the class to reflect that it is a concrete implementation of a Deque)






            share|improve this answer















            I do not see any problems with addCount as long as we add a disclaimer that this solution is not thread safe.



            The presented solution is a collection that can only accept int items. You can expand this if you add generic parameter to the class. Note that in this case, the internal array is of Object type and you let the compiler enforce type safety and also do auto-boxing to support primitive data items, just like in Java collections library. And while we mentioned that, you might want to consider making your solution implement the Deque interface from Java collections so that clients will work with a familiar API (of course you will want to change the name of the class to reflect that it is a concrete implementation of a Deque)







            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited Feb 7 at 9:50









            Zoe

            20519




            20519











            answered Feb 7 at 9:17









            Sharon Ben Asher

            2,073512




            2,073512






















                up vote
                1
                down vote













                Bugs



                If you call insertrear() and deletefront() repeatedly, you will eventually get an array out of bounds exception. There are at least two problems:



                This code in insertrear() can index past the end of the array:




                 rear = (rear - 1) % this.size;
                arr[rear + this.size] = key;



                If the first statement results in rear being 0, the second statement will try to access an element out of bounds.



                This code in deletefront() can cause front to become negative:




                 front = (front - 1) % this.size;



                which will cause the next addfront() call to throw an exception because it will try to use front as an array index without fixing it.



                I would recommend never letting front and rear go negative. First, this fixes your array bounds issues. Second, it also fixes an additional bug when you check front == rear and it should return true but it doesn't because one index is positive and one index is negative.



                Poor testing



                If you had exercised your code more, you would have caught these bugs. When writing tests for your code, you should make sure to stress it, not just do the bare minimum. For example, you should fill your queue to capacity and see what happens if you try to overfill it. You should also try every combination of filling from the front/rear with removing from the front/rear (4 separate tests at least).






                share|improve this answer



























                  up vote
                  1
                  down vote













                  Bugs



                  If you call insertrear() and deletefront() repeatedly, you will eventually get an array out of bounds exception. There are at least two problems:



                  This code in insertrear() can index past the end of the array:




                   rear = (rear - 1) % this.size;
                  arr[rear + this.size] = key;



                  If the first statement results in rear being 0, the second statement will try to access an element out of bounds.



                  This code in deletefront() can cause front to become negative:




                   front = (front - 1) % this.size;



                  which will cause the next addfront() call to throw an exception because it will try to use front as an array index without fixing it.



                  I would recommend never letting front and rear go negative. First, this fixes your array bounds issues. Second, it also fixes an additional bug when you check front == rear and it should return true but it doesn't because one index is positive and one index is negative.



                  Poor testing



                  If you had exercised your code more, you would have caught these bugs. When writing tests for your code, you should make sure to stress it, not just do the bare minimum. For example, you should fill your queue to capacity and see what happens if you try to overfill it. You should also try every combination of filling from the front/rear with removing from the front/rear (4 separate tests at least).






                  share|improve this answer

























                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    Bugs



                    If you call insertrear() and deletefront() repeatedly, you will eventually get an array out of bounds exception. There are at least two problems:



                    This code in insertrear() can index past the end of the array:




                     rear = (rear - 1) % this.size;
                    arr[rear + this.size] = key;



                    If the first statement results in rear being 0, the second statement will try to access an element out of bounds.



                    This code in deletefront() can cause front to become negative:




                     front = (front - 1) % this.size;



                    which will cause the next addfront() call to throw an exception because it will try to use front as an array index without fixing it.



                    I would recommend never letting front and rear go negative. First, this fixes your array bounds issues. Second, it also fixes an additional bug when you check front == rear and it should return true but it doesn't because one index is positive and one index is negative.



                    Poor testing



                    If you had exercised your code more, you would have caught these bugs. When writing tests for your code, you should make sure to stress it, not just do the bare minimum. For example, you should fill your queue to capacity and see what happens if you try to overfill it. You should also try every combination of filling from the front/rear with removing from the front/rear (4 separate tests at least).






                    share|improve this answer















                    Bugs



                    If you call insertrear() and deletefront() repeatedly, you will eventually get an array out of bounds exception. There are at least two problems:



                    This code in insertrear() can index past the end of the array:




                     rear = (rear - 1) % this.size;
                    arr[rear + this.size] = key;



                    If the first statement results in rear being 0, the second statement will try to access an element out of bounds.



                    This code in deletefront() can cause front to become negative:




                     front = (front - 1) % this.size;



                    which will cause the next addfront() call to throw an exception because it will try to use front as an array index without fixing it.



                    I would recommend never letting front and rear go negative. First, this fixes your array bounds issues. Second, it also fixes an additional bug when you check front == rear and it should return true but it doesn't because one index is positive and one index is negative.



                    Poor testing



                    If you had exercised your code more, you would have caught these bugs. When writing tests for your code, you should make sure to stress it, not just do the bare minimum. For example, you should fill your queue to capacity and see what happens if you try to overfill it. You should also try every combination of filling from the front/rear with removing from the front/rear (4 separate tests at least).







                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited Feb 7 at 9:54


























                    answered Feb 7 at 9:36









                    JS1

                    27k32876




                    27k32876




















                        up vote
                        0
                        down vote













                        With a circular buffer, you only need to keep track of two variables: writeIndex and itemCount.



                        • Both items are incremented when you write an item to the buffer


                        • itemCount is decremented when you read an item from the buffer

                        • You calculate the read index by subtracting the itemCount from the writeIndex

                        • You transition from the bottom of the buffer to the top by using modulus math

                        Here are the details:



                        Add data to the buffer:



                        writeIndex = ((writeIndex + 1) % BUFFER_SIZE)
                        if (itemCount < BUFFER_SIZE) itemCount++;
                        write data to buffer[writeIndex]


                        Remove data from the buffer:



                        if (itemCount > 0) 
                        readIndex = ((BUFFER_SIZE + writeIndex - itemCount + 1) % BUFFER_SIZE)
                        read data from the buffer[readIndex]
                        itemCount--;
                        }


                        Example:



                        BUFFER_SIZE = 6
                        writeIndex = 4
                        itemCount = 3

                        add item, new writeIndex = (4 + 1) % 6 = 5 % 6 = 5 new itemCount = 4
                        add item, new writeIndex = (5 + 1) % 6 = 6 % 6 = 0 new itemCount = 5
                        read item, new readIndex = (6+0-5+1) % 6 = 2%6 = 2 new itemCount = 4
                        read item, new readIndex = (6+0-4+1) % 6 = 3%6 = 3 new itemCount = 3


                        • % = modulus ... returns the remainder of a division

                        • 5%6 = 5/6, remainder 5

                        • 6%6 = 6/6, remainder 0

                        This example allows the overwriting of unread data.



                        Overwriting can be disabled by:



                        if (itemCount<BUFFER_SIZE) write logic


                        This example is not thread-safe. If you read and write in different threads, you'll need to add a locking mechanism to assure reading and writing operations do not occur at the same time.






                        share|improve this answer



























                          up vote
                          0
                          down vote













                          With a circular buffer, you only need to keep track of two variables: writeIndex and itemCount.



                          • Both items are incremented when you write an item to the buffer


                          • itemCount is decremented when you read an item from the buffer

                          • You calculate the read index by subtracting the itemCount from the writeIndex

                          • You transition from the bottom of the buffer to the top by using modulus math

                          Here are the details:



                          Add data to the buffer:



                          writeIndex = ((writeIndex + 1) % BUFFER_SIZE)
                          if (itemCount < BUFFER_SIZE) itemCount++;
                          write data to buffer[writeIndex]


                          Remove data from the buffer:



                          if (itemCount > 0) 
                          readIndex = ((BUFFER_SIZE + writeIndex - itemCount + 1) % BUFFER_SIZE)
                          read data from the buffer[readIndex]
                          itemCount--;
                          }


                          Example:



                          BUFFER_SIZE = 6
                          writeIndex = 4
                          itemCount = 3

                          add item, new writeIndex = (4 + 1) % 6 = 5 % 6 = 5 new itemCount = 4
                          add item, new writeIndex = (5 + 1) % 6 = 6 % 6 = 0 new itemCount = 5
                          read item, new readIndex = (6+0-5+1) % 6 = 2%6 = 2 new itemCount = 4
                          read item, new readIndex = (6+0-4+1) % 6 = 3%6 = 3 new itemCount = 3


                          • % = modulus ... returns the remainder of a division

                          • 5%6 = 5/6, remainder 5

                          • 6%6 = 6/6, remainder 0

                          This example allows the overwriting of unread data.



                          Overwriting can be disabled by:



                          if (itemCount<BUFFER_SIZE) write logic


                          This example is not thread-safe. If you read and write in different threads, you'll need to add a locking mechanism to assure reading and writing operations do not occur at the same time.






                          share|improve this answer

























                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            With a circular buffer, you only need to keep track of two variables: writeIndex and itemCount.



                            • Both items are incremented when you write an item to the buffer


                            • itemCount is decremented when you read an item from the buffer

                            • You calculate the read index by subtracting the itemCount from the writeIndex

                            • You transition from the bottom of the buffer to the top by using modulus math

                            Here are the details:



                            Add data to the buffer:



                            writeIndex = ((writeIndex + 1) % BUFFER_SIZE)
                            if (itemCount < BUFFER_SIZE) itemCount++;
                            write data to buffer[writeIndex]


                            Remove data from the buffer:



                            if (itemCount > 0) 
                            readIndex = ((BUFFER_SIZE + writeIndex - itemCount + 1) % BUFFER_SIZE)
                            read data from the buffer[readIndex]
                            itemCount--;
                            }


                            Example:



                            BUFFER_SIZE = 6
                            writeIndex = 4
                            itemCount = 3

                            add item, new writeIndex = (4 + 1) % 6 = 5 % 6 = 5 new itemCount = 4
                            add item, new writeIndex = (5 + 1) % 6 = 6 % 6 = 0 new itemCount = 5
                            read item, new readIndex = (6+0-5+1) % 6 = 2%6 = 2 new itemCount = 4
                            read item, new readIndex = (6+0-4+1) % 6 = 3%6 = 3 new itemCount = 3


                            • % = modulus ... returns the remainder of a division

                            • 5%6 = 5/6, remainder 5

                            • 6%6 = 6/6, remainder 0

                            This example allows the overwriting of unread data.



                            Overwriting can be disabled by:



                            if (itemCount<BUFFER_SIZE) write logic


                            This example is not thread-safe. If you read and write in different threads, you'll need to add a locking mechanism to assure reading and writing operations do not occur at the same time.






                            share|improve this answer















                            With a circular buffer, you only need to keep track of two variables: writeIndex and itemCount.



                            • Both items are incremented when you write an item to the buffer


                            • itemCount is decremented when you read an item from the buffer

                            • You calculate the read index by subtracting the itemCount from the writeIndex

                            • You transition from the bottom of the buffer to the top by using modulus math

                            Here are the details:



                            Add data to the buffer:



                            writeIndex = ((writeIndex + 1) % BUFFER_SIZE)
                            if (itemCount < BUFFER_SIZE) itemCount++;
                            write data to buffer[writeIndex]


                            Remove data from the buffer:



                            if (itemCount > 0) 
                            readIndex = ((BUFFER_SIZE + writeIndex - itemCount + 1) % BUFFER_SIZE)
                            read data from the buffer[readIndex]
                            itemCount--;
                            }


                            Example:



                            BUFFER_SIZE = 6
                            writeIndex = 4
                            itemCount = 3

                            add item, new writeIndex = (4 + 1) % 6 = 5 % 6 = 5 new itemCount = 4
                            add item, new writeIndex = (5 + 1) % 6 = 6 % 6 = 0 new itemCount = 5
                            read item, new readIndex = (6+0-5+1) % 6 = 2%6 = 2 new itemCount = 4
                            read item, new readIndex = (6+0-4+1) % 6 = 3%6 = 3 new itemCount = 3


                            • % = modulus ... returns the remainder of a division

                            • 5%6 = 5/6, remainder 5

                            • 6%6 = 6/6, remainder 0

                            This example allows the overwriting of unread data.



                            Overwriting can be disabled by:



                            if (itemCount<BUFFER_SIZE) write logic


                            This example is not thread-safe. If you read and write in different threads, you'll need to add a locking mechanism to assure reading and writing operations do not occur at the same time.







                            share|improve this answer















                            share|improve this answer



                            share|improve this answer








                            edited Feb 12 at 2:35









                            Jamal♦

                            30.1k11114225




                            30.1k11114225











                            answered Feb 12 at 1:55









                            Rodney Palmer

                            1




                            1






















                                 

                                draft saved


                                draft discarded


























                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186964%2fdeque-implemented-using-a-circular-array%23new-answer', 'question_page');

                                );

                                Post as a guest













































































                                Popular posts from this blog

                                Greedy Best First Search implementation in Rust

                                Function to Return a JSON Like Objects Using VBA Collections and Arrays

                                C++11 CLH Lock Implementation