如何实现一个循环缓冲区模型
来源:互联网 发布:手机录音剪切软件 编辑:程序博客网 时间:2024/06/05 00:38
下面是一个RingBuffer模型的完整实现,欢迎读者参考和指正:
typedef unsigned char BYTE;
template
class RingBuffer {
public:
typedef size_t size_type;
typedef GenericLocker
RingBuffer() : m_pushPos(0), m_popPos(0), m_count(0) {
assert(N > 0);
m_pRingBuffer = new BYTE[N];
}
~RingBuffer() { delete []m_pRingBuffer; }
RingBuffer(const RingBuffer
assert(N > 0);
m_pRingBuffer = new BYTE[N];
size_type rearLen = N - copy.m_popPos;
if (rearLen >= copy.m_count) {
::memmove(m_pRingBuffer,
©.m_pRingBuffer[copy.m_popPos],
copy.m_count);
}
else {
::memmove(m_pRingBuffer,
©.m_pRingBuffer[copy.m_popPos],
rearLen);
::memmove(m_pRingBuffer + rearLen,
copy.m_pRingBuffer,
copy.m_count - rearLen);
}
m_pushPos = m_count = copy.m_count;
}
RingBuffer& operator=(const RingBuffer
if (this != &other) {
_BufferLocker guard(m_mutex);
RingBuffer
_Swap(temp); // this->_Swap();
}
return (*this);
}
bool is_full() const {
_BufferLocker guard(m_mutex);
return (m_count == N);
}
bool is_empty() const {
_BufferLocker guard(m_mutex);
return (m_count == 0);
}
size_type size() const {
_BufferLocker guard(m_mutex);
return m_count;
}
size_type capacity() const { return N; }
size_type push(const BYTE *data, size_type length) {
assert(data != NULL);
_BufferLocker guard(m_mutex);
if (length == 0 || length > (N - m_count))
return 0;
size_type rearLen = N - m_pushPos; // 尾部剩余空间
if (length <= rearLen) {
::memmove(&m_pRingBuffer[m_pushPos], data, length);
m_pushPos += length;
m_pushPos %= N; // 调整新的push位置
}else{
::memmove(&m_pRingBuffer[m_pushPos], data, rearLen);
::memmove(m_pRingBuffer, data + rearLen, length - rearLen);
m_pushPos = length - rearLen; // 调整新的push位置
}
m_count += length;
return (length);
}
size_type pop(BYTE *buf, size_type length) {
assert(buf != NULL);
_BufferLocker guard(m_mutex);
if (length == 0 || length > m_count)
return 0;
size_type rearLen = N - m_popPos; // 尾部剩余数据
if (length <= rearLen) {
::memmove(buf, &m_pRingBuffer[m_popPos], length);
m_popPos += length;
m_popPos %= N; // 调整新的pop位置
}else {
::memmove(buf, &m_pRingBuffer[m_popPos], rearLen);
::memmove(buf + rearLen, m_pRingBuffer, length - rearLen);
m_popPos = length - rearLen; // 调整新的pop位置
}
m_count -= length;
return (length);
}
void clear() {
_BufferLocker guard(m_mutex);
m_pushPos = 0, m_popPos = 0, m_count = 0;
}
private:
BYTE *m_pRingBuffer; // buffer
size_type m_pushPos; // 新的push位置:pushPos=
// (popPos+count)% N
size_type m_popPos; // 新的pop位置
size_type m_count; // 有效字节数
CriticalSection m_mutex;
};
- 如何实现一个循环缓冲区模型
- 如何实现一个循环缓冲区模型
- 如何实现一个循环缓冲区模型
- 如何实现一个循环缓冲区模型
- 如何实现一个循环缓冲区模型
- 如何实现一个循环缓冲区模型
- 如何实现一个循环缓冲区模型
- 队列实现循环缓冲区
- 队列实现循环缓冲区
- 如何实现一个循环队列
- 如何实现一个循环队列
- 如何实现一个循环队列
- 如何实现一个循环队列
- 如何实现一个循环队列
- 如何实现一个循环队列
- 如何实现一个循环队列
- Objective-C实现循环缓冲区
- 如何高效的使用循环缓冲区
- [c#教程]c#中结构和类的区别
- 两本小书的命运 ---记《Effective STL》和《The Art Of Deception》两本书的出版翻译过程
- 关于char类型的取值范围
- [转]MySQL Cluster(MySQL 集群) 初试
- 如何实现一个循环队列
- 如何实现一个循环缓冲区模型
- 首批奥运歌曲MV——《Everyone is No.1》
- 开辟VisualFC(WTL WinxGUI 可视化开发工具)专栏
- 开源,选择Google Code还是Sourceforge?(修订版)
- 开始用Google Code的Issue
- [转]小谈MySQL字符集
- 用Erlang Inets轻松实现Web服务器
- VisualFC - WTL/WinxGUI可视化开发环境
- 我为什么选择了Erlang?