如何实现一个循环缓冲区模型
来源:互联网 发布:java开发工作流 编辑:程序博客网 时间:2024/05/22 02:27
下面是一个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实现循环缓冲区
- 如何高效的使用循环缓冲区
- boost源码剖析之:泛型编程精灵type_traits(rev#2)
- 如何实现一个循环队列
- amfphp连接数据库的实用方法
- .NET Generics vs. C++ Templates铪铪
- 轻松切换IP及IE代理设置
- 如何实现一个循环缓冲区模型
- Flex的一问一答
- 开辟VisualFC(WTL WinxGUI 可视化开发工具)专栏
- boost源码剖析之:泛型指针类any之海纳百川(rev#2)
- Ubuntu Web 版
- 开源,选择Google Code还是Sourceforge?(修订版)
- 在C++中侦测内嵌型别的存在(rev#2)
- Flex中替代cookit操作的方法
- 开始用Google Code的Issue