所以,我觉得在C ++中应该有一个很好的内置解决方案,但我不确定它是什么。
我需要一个队列(理想情况下是线程安全的,但如果需要的话,我可以自己将它包装起来),它可以有效地处理字节组 - 允许不同大小的读/写。
所以,界面看起来像是
//removes the first bytesToRead elements from the front of the queue and places them in array; returns the actual number of bytes dequeued
int dequeue(unsigned char *array, int bytesToRead)
//Adds bytesToWrite elements from array to the end of the queue; does nothing and returns 0 if this would exceed the queue's max size
int enqueue(unsigned char *array, int bytesToWrite)
我可以自己写一个没有太多困难,但似乎这应该是很容易就能完成的东西。
STL中最好的东西看起来可能是一个stringbuf - 我必须手动调用sgetc / pubseekoff,但看起来它会起作用。
我希望将此作为当前队列实现的替代品,这是一个性能问题;在此实现中读取的是队列中数据量的O(N)。 (这是一个非常天真的实现 - 每个dequeue都会导致队列中剩余数据的数组副本。)
附加要求(如果需要,我可以在包装器中实现这些要求): - 我需要能够指定缓冲区的最大大小 - 如果可用数据少于请求数据,则读取操作应检索所有可用数据 如果请求的写入超过最大大小并返回失败指示符,则写操作不应执行任何操作
所以,我的问题: 1)stringbuf是否足够?假设不需要调整大小,读/写操作O(1)是否相对于缓冲区中的数据量? (显然,它们可能是所请求项目数量的O(n)。)
2)还有其他一些我认为不足以满足的课程吗?
提前致谢!
答案 0 :(得分:8)
class queue {
std::deque<unsigned char> data;
public:
int enqueue(unsigned char *array, int bytesToWrite) {
data.insert(data.end(), array, array+bytesToWrite);
}
int dequeue(unsigned char *array, int bytesToRead) {
std::copy(data.begin(), data.begin()+bytesToRead, array);
// or, for C++11: std::copy_n(data.begin(), bytesToRead, array);
data.erase(data.begin(), data.begin()+bytesToRead);
}
};
对不起,我现在感觉不够雄心勃勃,无法添加锁定和你要求的返回值,但两者都不应该非常困难。但是,我没有摆弄你的返回值,而是更改接口以使用迭代器(或者,如果你真的坚持,则引用向量)。
保证插入/移除的元素数量是线性的。
答案 1 :(得分:1)
如果你想要一个非常快速有效的实现,我会选择一个简单的循环缓冲区实现,这意味着你可以在一个或两个副本中进行读取(取决于你是否包装缓冲区的结尾/开头) 。这允许你使用memcpy,根据我的经验,它几乎总是通过大量元素循环执行你的复制。
如果表现不那么重要,我会选择Jerry的答案。
答案 2 :(得分:0)
您可以使用std::stringstream
使用write
进入队列并使用read
弹出队列吗?
答案 3 :(得分:0)
根据建议,std::stringstream
可能是最简单,最好的解决方案。
另一个替代方案是std::deque
,它将为您提供所需的效率(从队列的任何一端进行所有读/写的常量摊销,并且如果容量是,则通常远小于重新分配的O(N)累)。唯一的缺点是std::deque
不支持指针运算(因为所有元素不一定是连续的(在块中)),所以你将无法进行块读/写操作,你将不得不迭代,如下:
std::deque<unsigned char> buf;
int dequeue(unsigned char *array, int bytesToRead) {
int result = std::min(bytesToRead, buf.size());
std::copy(buf.begin(), buf.begin() + result, array);
buf.erase(buf.begin(), buf.begin() + result);
return result;
};
int enqueue(unsigned char *array, int bytesToWrite) {
buf.insert(buf.end(), array, array + bytesToWrite);
return bytesToWrite;
};
如果达到最大容量,您应该检查后一个实现,并因此调整结果值。