title: C Shrinking size of circular buffer
body: <p>I am trying to finish up a circular buffer program that simply holds an array of stock quotes. However, I cannot seem to get my output correct when shrinking the circular buffer.</p>
  
  <p>The condition for shrinking the buffer is if 3/4 of the space in the buffer is free, shrink the buffer by 1/2. My code for shrinking/enlarging is as follows:</p>
  
  <pre><code>void cbuf_update(cbuf *cb_ptr, unsigned int time, double rate){
      int threeFourths;
      threeFourths = (cb_ptr-&gt;maxSize/4)*3;
  
      if((cb_ptr-&gt;maxSize != startSize) &amp;&amp; cb_ptr-&gt;freeSlots &gt;= threeFourths){
          printf("Shrinking!\n");
          int newSize;
          newSize = (cb_ptr-&gt;maxSize/2)-1;
          cbuf *newBuffer = malloc(sizeof(cbuf) + newSize * sizeof(quote));
          newBuffer -&gt;maxSize = (cb_ptr-&gt;maxSize/2);
          newBuffer -&gt;freeSlots = newBuffer-&gt;maxSize - (cb_ptr-&gt;maxSize - cb_ptr-&gt;freeSlots);
          int x;
          int counter;
          int y;
          counter = 0;
          if(cb_ptr-&gt;end &gt; cb_ptr-&gt;start){
              for(x = cb_ptr-&gt;end; x &lt; cb_ptr-&gt;maxSize; x ++){
                  if(cb_ptr-&gt;quoteBuffer[x].time != -1){
                      newBuffer-&gt;quoteBuffer[counter].time = cb_ptr-&gt;quoteBuffer[x].time;
                      newBuffer-&gt;quoteBuffer[counter].rate = cb_ptr-&gt;quoteBuffer[x].rate;
                      counter ++;
                  }
              }   
              for(y = 0; y &lt; cb_ptr-&gt;start; y++){
                  if(cb_ptr-&gt;quoteBuffer[y].time != -1){
                      newBuffer-&gt;quoteBuffer[counter].time = cb_ptr-&gt;quoteBuffer[y].time;
                      newBuffer-&gt;quoteBuffer[counter].rate = cb_ptr-&gt;quoteBuffer[y].rate;
                      counter++;
                  }
              }
          }
          if(cb_ptr-&gt;end &lt; cb_ptr-&gt;start){
              //printf("second condition\n");
              for(x = cb_ptr-&gt;end; x &lt; cb_ptr-&gt;start; x ++){
                  if(cb_ptr-&gt;quoteBuffer[x].time != -1){
  
                      newBuffer-&gt;quoteBuffer[counter].time = cb_ptr-&gt;quoteBuffer[x].time;
                      newBuffer-&gt;quoteBuffer[counter].rate = cb_ptr-&gt;quoteBuffer[x].rate;
                      counter ++;
                  }
              }       
          }
          newBuffer-&gt;start = counter;
          newBuffer-&gt;end = 0;
          cbuf_dump(newBuffer);
          *cb_ptr = *newBuffer;       
  
      }
  
  
      if(cb_ptr-&gt;freeSlots == 0){
          printf("EXPANDING CIRCULAR BUFFER!\n");
          int newSize;
          newSize = (cb_ptr-&gt;maxSize * 2) - 1;
          cbuf *newBuffer = malloc(sizeof(cbuf) + newSize * sizeof(quote));
          newBuffer-&gt;maxSize = cb_ptr-&gt;maxSize * 2;
          newBuffer-&gt;start = cb_ptr-&gt;start;
          newBuffer-&gt;end = cb_ptr-&gt;end;
          newBuffer-&gt;freeSlots = newBuffer-&gt;maxSize - cb_ptr-&gt;maxSize;
          int x;
          int counter;
          counter = 0;
          for(x = cb_ptr-&gt;end; x &lt; cb_ptr-&gt;maxSize; x ++){
              newBuffer-&gt;quoteBuffer[counter].time = cb_ptr-&gt;quoteBuffer[x].time;
              newBuffer-&gt;quoteBuffer[counter].rate = cb_ptr-&gt;quoteBuffer[x].rate;
              counter ++;
          }
          int y;
          for(y = 0; y &lt; cb_ptr-&gt;start; y ++){
              newBuffer-&gt;quoteBuffer[counter].time = cb_ptr-&gt;quoteBuffer[y].time;
              newBuffer-&gt;quoteBuffer[counter].rate = cb_ptr-&gt;quoteBuffer[y].rate;
              counter++;
          }
          newBuffer-&gt;start = cb_ptr-&gt;maxSize;
          newBuffer-&gt;end = 0;
  
          *cb_ptr = *newBuffer;
  
  
  
      }   
  
  
      //If the start pointer has reached the end of the array and there are still free slots back at the beginning of the array, loop back.   
      if(cb_ptr-&gt;start == cb_ptr-&gt;maxSize &amp;&amp; cb_ptr-&gt;freeSlots &gt; 0){
          //printf("Cannot insert time: %d\n", time);
          cb_ptr-&gt;start = 0;
      };
      cb_ptr-&gt;quoteBuffer[cb_ptr-&gt;start].time = time;
      cb_ptr-&gt;quoteBuffer[cb_ptr-&gt;start].rate = rate;
      cb_ptr-&gt;start = cb_ptr-&gt;start +1;
      cb_ptr-&gt;freeSlots = cb_ptr-&gt;freeSlots -1;
  
      //If any quote in the array is older than 5 minutes when compared to the current quote, flag it as null and move the end pointer up one.
      //Also, clear up a freeSlot.
      int x;
      for(x = cb_ptr-&gt;end; x &lt; (cb_ptr-&gt;start); x ++){
  
          if((time) - (cb_ptr-&gt;quoteBuffer[x].time) &gt;= fiveMin){
              cb_ptr-&gt;end = cb_ptr-&gt;end + 1;
              cb_ptr-&gt;quoteBuffer[x].time = -1;
              cb_ptr-&gt;quoteBuffer[x].rate = -1.00;
              cb_ptr-&gt;freeSlots = cb_ptr-&gt;freeSlots +1;
          }
      }
  
  
  }
  </code></pre>
  
  <p>Code for dumping the buffer (printing it) is as follows:</p>
  
  <pre><code>void cbuf_dump(cbuf *cb_ptr){
      printf("*****\t DUMPING \t*****\n");
  
      if(cb_ptr-&gt;start &gt; cb_ptr-&gt;end){
          //printf("first dump cond.\n");
          printf("start: %d\t end:%d\n", cb_ptr-&gt;start, cb_ptr-&gt;end);
          int x;
          for(x = cb_ptr-&gt;end; x&lt;(cb_ptr-&gt;start); x++){
              printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr-&gt;quoteBuffer[x].time),(cb_ptr-&gt;quoteBuffer[x].rate));
          }
      }
  
      /*
      If the start pointer has been wrapped back around to the beginning of the circular buffer, then the end pointer must be at an index that is         greater than the start index. For this, we need to print out the data ranging from the end pointer to the end of the array, and then the        data from the start pointer to the end pointer provided the data isn't flagged as null (having -1 for both entries in the quote struct).
      */
      if(cb_ptr-&gt;end &gt;= cb_ptr-&gt;start){
          //printf("Secondary condition\n");
          int x;
          for(x=cb_ptr-&gt;end; x &lt; cb_ptr-&gt;maxSize; x ++){
              printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr-&gt;quoteBuffer[x].time),(cb_ptr-&gt;quoteBuffer[x].rate));
          }
          int y;
          for(y = 0; y &lt; cb_ptr-&gt;start; y ++){
              if(cb_ptr-&gt;quoteBuffer[y].time != -1){
                  printf("%d.) time = %d, \t rate = %f\n",y,(cb_ptr-&gt;quoteBuffer[y].time),(cb_ptr-&gt;quoteBuffer[y].rate));
              }
          }
      }
  
      //printf("freeslots = %d\n", cb_ptr-&gt;freeSlots);
  }
  </code></pre>
  
  <p>and finally, my main is:</p>
  
  <pre><code>int main(){
  
      cbuf *cb1 ;
  
      cb1 = cbuf_init() ;
      cbuf_update(cb1, 60, 1.291) ;
      cbuf_update(cb1, 63, 1.287) ;
      cbuf_update(cb1, 63, 1.231) ;
      cbuf_update(cb1, 69, 1.229) ;
      cbuf_update(cb1, 72, 1.247) ;
      cbuf_update(cb1,361,1.291);
      cbuf_update(cb1, 411, 1.291) ;
      cbuf_update(cb1, 412, 1.281) ;
      cbuf_update(cb1, 413, 1.292) ;
      cbuf_update(cb1, 414, 1.284) ;
      cbuf_update(cb1, 414, 1.290) ;
      cbuf_update(cb1, 511, 1.241) ;
      cbuf_update(cb1, 512, 1.251) ;
      cbuf_update(cb1, 513, 1.232) ;
      cbuf_update(cb1, 514, 1.202) ;
      cbuf_update(cb1, 517, 1.119) ;
      cbuf_update(cb1, 551, 1.080) ;
      cbuf_update(cb1, 552, 1.081) ;
      cbuf_update(cb1, 553, 1.079) ;
      cbuf_update(cb1, 554, 1.088) ;
      cbuf_update(cb1, 561, 1.072) ;
      cbuf_update(cb1, 562, 1.113) ;
      cbuf_update(cb1, 563, 1.091) ;
      cbuf_update(cb1, 564, 1.092) ;
      cbuf_update(cb1, 571, 1.089) ;
      cbuf_update(cb1, 572, 1.073) ;
      cbuf_update(cb1, 573, 1.061) ;
      cbuf_update(cb1, 574, 1.111) ;
      cbuf_update(cb1, 581, 1.119) ;
      cbuf_update(cb1, 582, 1.123) ;
      cbuf_update(cb1, 583, 1.151) ;
      cbuf_update(cb1, 584, 1.153) ;  
      cbuf_dump(cb1);
      cbuf_update(cb1, 750, 1.200) ;
      cbuf_dump(cb1) ;
      cbuf_update(cb1, 818, 1.210) ;
      cbuf_dump(cb1) ;
      cbuf_update(cb1, 868, 1.230) ;
      cbuf_dump(cb1) ;
      cbuf_update(cb1, 878, 1.230) ;
      cbuf_dump(cb1) ;
      cbuf_update(cb1, 900, 1.240) ;
      cbuf_dump(cb1) ;
      cbuf_update(cb1, 2000, 1.240) ;
      cbuf_dump(cb1) ;
      return 0;
  
  }
  </code></pre>
  
  <p>The output towards the end should be:</p>
  
  <pre><code>*** Circular Buffer Dump ***
  size = 11, max = 40
  start = 19, end = 29
  
  19: time = 571,  rate = 1.089000
  20: time = 572,  rate = 1.073000
  21: time = 573,  rate = 1.061000
  22: time = 574,  rate = 1.111000
  23: time = 581,  rate = 1.119000
  24: time = 582,  rate = 1.123000
  25: time = 583,  rate = 1.151000
  26: time = 584,  rate = 1.153000
  27: time = 750,  rate = 1.200000
  28: time = 818,  rate = 1.210000
  29: time = 868,  rate = 1.230000
  ****************************
  
  Shrinking circular buffer: old max = 40, new max = 20
  
  
  *** Circular Buffer Dump ***
  size = 8, max = 20
  start = 3, end = 10
  
  3: time = 581,  rate = 1.119000
  4: time = 582,  rate = 1.123000
  5: time = 583,  rate = 1.151000
  6: time = 584,  rate = 1.153000
  7: time = 750,  rate = 1.200000
  8: time = 818,  rate = 1.210000
  9: time = 868,  rate = 1.230000
  10: time = 878,  rate = 1.230000
  ****************************
  
  Shrinking circular buffer: old max = 20, new max = 10
  
  
  *** Circular Buffer Dump ***
  size = 5, max = 10
  start = 1, end = 5
  
  1: time = 750,  rate = 1.200000
  2: time = 818,  rate = 1.210000
  3: time = 868,  rate = 1.230000
  4: time = 878,  rate = 1.230000
  5: time = 900,  rate = 1.240000
  ****************************
  
  
  
  *** Circular Buffer Dump ***
  size = 1, max = 10
  start = 6, end = 6
  
  6: time = 2000,  rate = 1.240000
  ****************************
  </code></pre>
  
  <p>However, my output keeps finishing up like this:</p>
  
  <pre><code>*****    DUMPING    *****
  start: 30    end:19
  19.) time = 571,     rate = 1.089000
  20.) time = 572,     rate = 1.073000
  21.) time = 573,     rate = 1.061000
  22.) time = 574,     rate = 1.111000
  23.) time = 581,     rate = 1.119000
  24.) time = 582,     rate = 1.123000
  25.) time = 583,     rate = 1.151000
  26.) time = 584,     rate = 1.153000
  27.) time = 750,     rate = 1.200000
  28.) time = 818,     rate = 1.210000
  29.) time = 868,     rate = 1.230000
  *****    DUMPING    *****
  start: 31    end:23
  23.) time = 581,     rate = 1.119000
  24.) time = 582,     rate = 1.123000
  25.) time = 583,     rate = 1.151000
  26.) time = 584,     rate = 1.153000
  27.) time = 750,     rate = 1.200000
  28.) time = 818,     rate = 1.210000
  29.) time = 868,     rate = 1.230000
  30.) time = 878,     rate = 1.230000
  Shrinking!
  *****    DUMPING    *****
  start: 9     end:8
  8.) time = 900,      rate = 1.240000
  Shrinking!
  *****    DUMPING    *****
  start: 2     end:1
  1.) time = 2000,     rate = 1.240000
  </code></pre>
  
  <p>Obviously the formatting is different, but the numbers should match up. I cant quite figure out why as soon as the time of 900 is added to my buffer, it seems to think the time codes 581-878 are all greater than five minutes away from 900 (the criteria for printing is only printing the most recent quotes in a 5 minute timespan). I realize 581-600 are obviously going to be discarded, but the rest should still remain in the buffer.</p>