/************************************************ * Memory Queue is a special linear table, * which is a first in, * first out (FIFO) data structure * * create zoufuzhou 20201001 * ************************************************/ #ifndef _MEM_QUEUE_CACHE_HPP_ #define _MEM_QUEUE_CACHE_HPP_ #include #include template class CMemQueue { typedef struct { unsigned int maxsize; unsigned int size; unsigned int head; unsigned int tail; } HEAD; // Local variable private: std::mutex m_mutex; // Memory variable private: HEAD *p_head; T *p_ptr; private: void init(const string &tableName) { char *ptr = (char *)GlobMem::GetInstancePtr()->GetTablePtr(tableName); if (ptr == nullptr) { p_ptr = nullptr; p_head = nullptr; return; } p_head = (HEAD *)(ptr); p_ptr = (T *)(ptr + sizeof(HEAD)); }; private: // 提取pop操作的核心逻辑,但不加锁(由公有方法加锁) T *pop_core() { if (this->empty_core()) return nullptr; T *item = p_ptr + p_head->head; p_head->head = (p_head->head + 1) % p_head->maxsize; p_head->size--; return item; } bool empty_core() const { return p_head == nullptr || p_head->size == 0; } public: CMemQueue(const string &tableName) { this->init(tableName); // assert(p_head->maxsize>1); // p_head->size = p_head->size%p_head->maxsize; // p_head->head = p_head->head%p_head->maxsize; // p_head->tail = p_head->tail%p_head->maxsize; }; CMemQueue(const string &tableName, unsigned int maxsize) { // assert(maxsize>1); this->init(tableName); std::lock_guard lock(m_mutex); // 使用RAII锁 p_head->maxsize = maxsize; if (p_head->size != p_head->maxsize) { p_head->size = 0; p_head->head = 0; p_head->tail = 0; } else { p_head->size = p_head->size % p_head->maxsize; p_head->head = p_head->head % p_head->maxsize; p_head->tail = p_head->tail % p_head->maxsize; } }; ~CMemQueue(){}; T *operator()(void) { return p_ptr; }; unsigned int max_size(void) { std::lock_guard lock(m_mutex); // 加锁保护 return p_head->maxsize; } unsigned int size(void) { if (p_head == nullptr) return 0; std::lock_guard lock(m_mutex); // 加锁保护 return p_head->size; } T *operator[](unsigned int i) { if (p_ptr == nullptr) return nullptr; return p_ptr + i; }; void push(T *t) { if (p_ptr == nullptr || p_head == nullptr || t == nullptr) { return; } std::lock_guard lock(m_mutex); // 保护整个push操作 if (p_head->size < p_head->maxsize) { p_head->size++; } else { pop_core(); } memcpy(p_ptr + p_head->tail, t, sizeof(T)); p_head->tail = (p_head->tail + 1) % p_head->maxsize; }; T *pop(void) { std::lock_guard lock(m_mutex); // 加锁保护 return pop_core(); }; bool empty(void) { std::lock_guard lock(m_mutex); // 加锁保护 return empty_core(); }; T *back(void) { std::lock_guard lock(m_mutex); if (this->empty_core()) return nullptr; unsigned int index = (p_head->tail == 0) ? p_head->maxsize - 1 : p_head->tail - 1; return p_ptr + index; }; T *front(void) { std::lock_guard lock(m_mutex); if (this->empty_core()) return nullptr; return p_ptr + p_head->head; }; void clear(void) { if (p_head == nullptr) return; std::lock_guard lock(m_mutex); // 加锁保护 p_head->size = 0; p_head->head = 0; p_head->tail = 0; }; }; #endif