zoukankan      html  css  js  c++  java
  • 环形队列实现

    在实际应用中,环形队列通常用在只能buffer固定大小数据量的场景,如audio driver.

    在buffer数据时,有一个writePointer来记录上层app往buffer写的位置,用一个readPointer来记录audio driver读的位置。

    #include <string.h>
    #include <stdio.h>
    #define RING_BUF_SIZE 10
    typedef struct _RingBuffer{
      int _data[RING_BUF_SIZE];
      int _writePointer;
      int _readPointer;
      int _size;
    }RingBuffer;
    void ringBuffer_init(RingBuffer *pRingBuffer)
    {
      memset(pRingBuffer->_data, 0 ,sizeof(pRingBuffer->_data));
      pRingBuffer->_writePointer = 0;
      pRingBuffer->_readPointer = 0;
      pRingBuffer->_size = 0;
    }

    void ringBuffer_write(RingBuffer *pRingBuffer, int *data, int len)
    {
      if (pRingBuffer->_size + len > RING_BUF_SIZE)
      {
        printf("ring buffer full ");
        return ;
      }
      int newWritePointer = 0;
      int loop = 0;
      newWritePointer = pRingBuffer->_writePointer + len;
      if (newWritePointer >= RING_BUF_SIZE)
      {
        newWritePointer -= RING_BUF_SIZE;
        loop = 1;
      }
      if (loop)
      {
        memcpy(pRingBuffer->_data + pRingBuffer->_writePointer, data, (RING_BUF_SIZE - pRingBuffer->_writePointer)*sizeof(int));
        memcpy(pRingBuffer->_data, data + RING_BUF_SIZE - pRingBuffer->_writePointer, (len - (RING_BUF_SIZE - pRingBuffer->_writePointer))*sizeof(int));
      }
      else
      {
        memcpy(pRingBuffer->_data + pRingBuffer->_writePointer, data, len*sizeof(int));
      }
      pRingBuffer->_size += len;
      pRingBuffer->_writePointer = newWritePointer;
    }

    void ringBuffer_read(RingBuffer *pRingBuffer, int *data, int len)
    {
      if (len > pRingBuffer->_size)
      {
        printf("no enough data ");
        return;
      }
      int newReadPointer = 0;
      int loop = 0;
      newReadPointer = pRingBuffer->_readPointer + len;
      if (newReadPointer >= RING_BUF_SIZE)
      {
        newReadPointer -= RING_BUF_SIZE;
        loop = 1;
      }
      if (loop)
      {
        memcpy(data, pRingBuffer->_data + pRingBuffer->_readPointer,(RING_BUF_SIZE - pRingBuffer->_readPointer)*sizeof(int));
        memcpy(data + RING_BUF_SIZE - pRingBuffer->_readPointer, pRingBuffer->_data, (len - (RING_BUF_SIZE - pRingBuffer->_readPointer))*sizeof(int));
      }
      else
      {
      memcpy(data, pRingBuffer->_data + pRingBuffer->_readPointer, len * sizeof(int));
      }
      pRingBuffer->_size -= len;
      pRingBuffer->_readPointer = newReadPointer;
    }
    int main(int argc, char **argv)
    {
      int writeData1[6] = {0,1,2,3,4,5};
      int writeData2[6] = {6,7,8,9,10,11};
      int readData[4];
      RingBuffer _ringBuffer;
      ringBuffer_init(&_ringBuffer);
      ringBuffer_write(&_ringBuffer, writeData1, 6);
      printf("wp:%d, rp:%d, sz:%d ", _ringBuffer._writePointer, _ringBuffer._readPointer, _ringBuffer._size);
      int idx = 0;
      for (idx = _ringBuffer._readPointer; idx < _ringBuffer._writePointer; idx++)
      {
        printf("data after write:%d ", _ringBuffer._data[idx]);
      }
      ringBuffer_read(&_ringBuffer, readData, 4);
      for (idx = _ringBuffer._readPointer; idx < _ringBuffer._writePointer; idx++)
      {
        printf("data after read:%d ", _ringBuffer._data[idx]);
      }
      printf("wp:%d, rp:%d, sz:%d ", _ringBuffer._writePointer, _ringBuffer._readPointer, _ringBuffer._size);
      for (idx = 0; idx < 4; idx++)
      {
        printf("read data:%d ", readData[idx]);
      }
      ringBuffer_write(&_ringBuffer, writeData2, 6);
      printf("wp:%d, rp:%d, sz:%d ", _ringBuffer._writePointer, _ringBuffer._readPointer, _ringBuffer._size);

      for (idx = _ringBuffer._readPointer; idx < RING_BUF_SIZE; idx++)
      {
        printf("data after write:%d ", _ringBuffer._data[idx]);
      }

      for (idx = 0; idx < _ringBuffer._writePointer; idx++)
      {
        printf("data after write:%d ", _ringBuffer._data[idx]);
      }
      return 0;
    }

    运行结果如下:

  • 相关阅读:
    自己改了个{svn服务器端绿色版}
    Android去掉顶部的阴影
    SqliteOpenHelper的onUpgrade()死活不运行的解法
    前端模拟发送数据/调试的好工具:Chrome下的PostmanREST Client
    mouseenter & mouseleave VS mouseover & mouseout
    Android WindowManager$BadTokenException异常应对案例
    Eclipse快捷键大全(转载)
    360桌面JSAPI一个诡异的bug:客户端与网页通过js通信
    《你在哪》1.34强势发布,新增“图片墙”
    经过一个月的奋斗,我的第一个Android作品《麦芒》诞生了
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6139121.html
Copyright © 2011-2022 走看看