先记录一下 目前看起来还有很大优化空间
spsc
不支持深拷贝
#ifndef FAC_PLATFORMNEW_FIXEDQUEUE_H
#define FAC_PLATFORMNEW_FIXEDQUEUE_H
#include <iostream>
#include <vector>
#include <atomic>
#include <chrono>
#include <thread>
#include <string.h>
template<typename T>
class FixedQueue {
public:
explicit FixedQueue(size_t capacity) : capacity_(capacity), queue_(capacity) {}
FixedQueue(const FixedQueue&) = delete;
~FixedQueue() { clear(); }
bool Enqueue(T item) {
size_t currentTail = write_.load(std::memory_order_relaxed);
size_t nextTail = (currentTail + 1) % capacity_;
while(nextTail == read_.load(std::memory_order_acquire)) {
if (is_full()) {
// Queue is full, resize the queue
size_t newCapacity = capacity_ * 2;
std::vector<T> newQueue(newCapacity);
// Copy existing elements to the new queue
// for (size_t i = 0; i < capacity_; ++i) {
// newQueue[i] = queue_[(nextTail + i) % capacity_];
// }
// 第一段memcpy:复制从nextTail开始到队列末尾的元素
size_t elementsToEnd = capacity_ - nextTail;
if(elementsToEnd!=0) memcpy(newQueue.data(), &queue_[nextTail], elementsToEnd * sizeof(T));
// 第二段memcpy:复制从队列开头到nextTail之前的元素
if(currentTail != 0) memcpy(newQueue.data() + elementsToEnd, queue_.data(), currentTail * sizeof(T));
//fake copy cost time
std::cout << "Queue is full:" << nextTail << "capacity: " << capacity_ << ", resized to new capacity: " << newCapacity << std::endl;
// std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Update head and tail indices
// std::cout << read_.load() << std::endl;
int cr = read_.load(std::memory_order_acquire);
read_.store((cr - nextTail + capacity_) % capacity_, std::memory_order_release);
currentTail = capacity_-1;
nextTail = capacity_;
// Replace the existing queue with the new queue
queue_ = std::move(newQueue);
capacity_ = newCapacity;
}
}
// std::cout << "set value and write ptr ++ ct: " << currentTail<< std::endl;
queue_[currentTail] = item;
write_.store(nextTail, std::memory_order_release);
return true;
}
T Dequeue() {
size_t currentHead = read_.load(std::memory_order_acquire);
// std::cout << " Dequeue currenthead: " << currentHead << std::endl;
while(currentHead == write_.load(std::memory_order_acquire)) {
std::cout << "queue is empty, unable to dequeue item" << std::endl;
// std::this_thread::sleep_for(std::chrono::milliseconds(20));
size_t currentHead = read_.load(std::memory_order_acquire);
}
T item = queue_[currentHead]; // 清空已出队的元素
// std::cout << "Dequeue item index: " << currentHead;
read_.store((currentHead + 1) % capacity_, std::memory_order_release);
return item;
}
bool is_full() const {
size_t currentTail = write_.load(std::memory_order_relaxed);
size_t nextTail = (currentTail + 1) % capacity_;
return nextTail == read_.load(std::memory_order_acquire);
}
bool is_empty() const {
return read_.load(std::memory_order_acquire) == write_.load(std::memory_order_acquire);
}
void clear() {
read_.store(0, std::memory_order_relaxed);
write_.store(0, std::memory_order_relaxed);
}
private:
size_t capacity_;
std::atomic<size_t> read_{0};
std::atomic<size_t> write_{0};
std::vector<T> queue_;
};
#endif //FAC_PLATFORMNEW_FIXEDQUEUE_H