Search code examples
ccircular-buffer

Simple circular buffer: Need to extend function to overwrite old data


I'm trying to implement an simple Circular Buffer with overwriting old data (Just experimenting with buffers). Actually I implemented a buffer but it is not overwriting the old data. When the buffer is full it will not add new data to the array.

I have the following:

//Struct with 8 bytes
typedef struct
{
   int8 data_A;                        
   int16 data_B;
   int8 data_C;
   int32 data_D; 
} MyData_Struct_t

//The Circular buffer struct
typedef struct {
   MyData_Struct_t  myData[10]; // 10 elemtns of MyData_Struct_t
   int8 write_idx
   int8 read_idx
   int8 NrOfMessagesinTheQue
} RingBuffer


static MyData_Struct_t  myDataVariable =  {0}; // Instance of MyData_Struct_t
static RingBuffer myRingBuffer= { 0 };      // Instance of myRingBuffer

myDataVariable.data_A = getData(A);  // Lets' say getData() function is called cyclic and new data is received
myDataVariable.data_B = getData(B);  
myDataVariable.data_C = getData(C);   
myDataVariable.data_D = getData(D); 

// Here I call a function to fill the array with data
writeDataToRingbuffer(&myRingBuffer, &myDataVariable); 

void writeDataToRingbuffer(RingBuffer *pBuf, MyData_Struct_t *Data)
{
   if (10 <= pBuf->NrOfMessagesinTheQue)
   {
        // Buffer is Full
   }

   else if (pBuf->write_idx < 10)
   {
      (void)memcpy(&pBuf->myData[pBuf->write_idx], Data, 
sizeof(MyData_Struct_t));  //myData will be read later by another function

      if ((10 - 1u) == pBuf->write_idx)
      {
         pBuf->write_idx = 0u;
      }

      else
      {
         pBuf->write_idx += 1;
      }

      pBuf->NrOfMessagesinTheQue++;
   }

   else
   {
      // Out of boundary
   }
}

I need some ideas how to extend this function in order to overwrite old data?

Would be very thankful!


Solution

  • If you just want to overwrite the oldest data just use the index modulo the size of the buffer:

    #define BUFFER_SIZE 10  // size of myData
    
    void writeDataToRingbuffer(RingBuffer *pBuf, MyData_Struct_t *Data)
    {
        (void)memcpy(&pBuf->myData[pBuf->write_idx % BUFFER_SIZE], Data, 
             sizeof(MyData_Struct_t));  //myData will be read later by another function
    
        pBuf->write_idx += 1;
        pBuf->NrOfMessagesinTheQue++;
    }
    

    With this method you can also combine write_idx and NrOfMessageinTheQue since you never have to reset the index to 0 now.