环形缓冲区的模板类实现

环形缓冲区

  • 什么是环形缓冲区
    环形缓冲区用于表示一个固定尺寸、头尾相连的缓冲区,通常用于缓存数据。环形缓冲区的主要特点是最大缓存数据量是固定的,当缓冲区满之后,会自动删除头部数据。
  • 应用场景
    总的来说,只要是固定长度的数据缓存,都可以使用环形缓冲区。个人用的较多的地方主要是视频缓存。

环形缓冲区代码示例

  • 具体代码
#include <mutex>;
#include <iostream>;
using namespace std;

//类名:环形缓冲区类
//功能:实现任意类的环形缓冲区存储
template<typename T>
class RingBuffer
{
public:
    //函数功能:环形缓冲区构造函数
    //参数:    int iMaxBufferSize[IN]                   -- 环形缓冲区最大长度,长度应大于0
    //返回值:  无
    RingBuffer(int iMaxBufferSize):
        m_MaxBufSize(iMaxBufferSize),
        m_Buffer(NULL),
        m_CopyBuffer(NULL)
    {
        _ASSERTE(m_MaxBufSize > 0);

        this->m_Buffer = new T[m_MaxBufSize];

        _ASSERT(this->m_Buffer != NULL);

        this->m_CopyBuffer = new T[m_MaxBufSize];

        _ASSERT(this->m_CopyBuffer != NULL);
    }

    //函数功能:环形缓冲区析构函数
    //参数:    无
    //返回值:  无
    ~RingBuffer()
    {
        this->m_mtElement.lock();
        if (m_Buffer != NULL)
        {
            if (m_MaxBufSize>1)
            {
                delete[] m_Buffer;
                delete[] m_CopyBuffer;
            }
            else if (1==m_MaxBufSize)
            {
                delete m_Buffer;
                delete m_CopyBuffer;
            }

            m_Buffer = NULL;
            m_CopyBuffer = NULL;
        }
        this->m_mtElement.unlock();
    }

    //函数功能:环形缓冲区析构函数
    //参数:    const T element[IN]                   -- 要插入的元素
    //返回值:  无
    bool Append(const T element)
    {
        bool bRet = true;
        this->m_mtElement.lock();
        if (this->m_CurElementNum<=(this->m_MaxBufSize-1))
        {
            //尚有富余空间,直接插入
            this->m_CurElementNum++;
            this->m_Buffer[this->m_CurElementNum - 1] = element;
        }
        else
        {
            //空间已满,需要去掉最前面的,然后插入
            memcpy(this->m_CopyBuffer, &(this->m_Buffer[1]), (this->m_CurElementNum - 1) * sizeof(T));
            this->m_CopyBuffer[this->m_CurElementNum - 1] = element;

            memcpy(this->m_Buffer, this->m_CopyBuffer, this->m_CurElementNum * sizeof(T));
        }
        this->m_mtElement.unlock();
        return bRet;
    }

    //函数功能:环形缓冲区打印
    //参数:    const T element[IN]                   -- 要插入的元素
    //返回值:  无
    bool Print()
    {
        bool bRet = true;
        this->m_mtElement.lock();
        cout << "环形缓冲区结果如下:" << endl;
        for (int i = 0; i < this->m_CurElementNum; i++)
        {
            cout << "    "<<this->m_Buffer[i] << endl;
        }
        cout << endl;
        this->m_mtElement.unlock();
        return bRet;
    }

    //函数功能:检查序列中是否包容某个元素
    //参数:    const T element[IN]                   -- 要检查的元素
    //返回值:  bool                                  -- 包含指定元素,则返回True;否则返回False
    bool Contains(const T element)
    {
        bool bRet = false;
        this->m_mtElement.lock();
        for (int i = 0; i < this->m_CurElementNum; i++)
        {
            if (element==this->m_Buffer[i])
            {
                bRet = true;
                break;
            }
        }
        this->m_mtElement.unlock();
        return bRet;
    }

    //函数功能:获取指定序列中的值
    //参数:    const T element[IN]                   -- 要检查的元素
    //返回值:  bool                                  -- 包含指定元素,则返回True;否则返回False
    T& operator[](int index)
    {
        T ret;
        this->m_mtElement.lock();
        _ASSERTE(index <= this->m_CurElementNum - 1);
        ret = this->m_Buffer[index];
        this->m_mtElement.unlock();
        return ret;
    }
private:
    int m_MaxBufSize;                      //环形缓冲区容最大长度
    int m_CurElementNum;                   //当前元素数量
    T* m_Buffer;                           //环形缓冲区
    T* m_CopyBuffer;                       //复制缓冲区,为了加快速度
    mutex m_mtElement;                     //互斥锁
};

int main()
{
    RingBuffer<int>* pTempRingBuffer = new RingBuffer<int>(100);

    if (pTempRingBuffer!=NULL)
    {
        for (int i = 0; i < 100; i++)
        {
            pTempRingBuffer->Append(i);
        }

        for (int i = 0; i < 10; i++)
        {
            cout << (*pTempRingBuffer)[i] << endl;
        }

        pTempRingBuffer->Print();
        delete pTempRingBuffer;
    }

    getchar();
    return 0;
}
  • 相关说明
    该类编译环境为VS2015,可以正常编译通过
    该类支持多线程操作,为了保证多线程的安全性,使用MUTEX互斥锁,如果是早期开发环境,也可以改为临界区
    为了降低移植难度,没有使用容器类,直接通过动态数组来存储缓存数据
    在插入数据时,为了减少频繁的数据移动,采用了一个备份数组来交换数据
  • 测试平台
    测试平台:操作系统:Windows7
    CPU: i5 6400 2.70GHZ
    内存: 8G
  • 性能指标
    当缓冲区长度为100,单线程的插入性能如下:
    插入一亿个int数据的耗时:7950ms
    插入单个int数据耗时:0.0000795ms。

猜你喜欢

转载自blog.csdn.net/u014337397/article/details/80340497