eis/inc/zlib/MemQueue.hpp

156 lines
3.7 KiB
C++
Raw Normal View History

/************************************************
* 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 <glob/GlobMem.h>
#include <mutex>
template <typename T> 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<std::mutex> 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<std::mutex> lock(m_mutex); // 加锁保护
return p_head->maxsize;
}
unsigned int size(void) {
if (p_head == nullptr)
return 0;
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> lock(m_mutex); // 加锁保护
return pop_core();
};
bool empty(void) {
std::lock_guard<std::mutex> lock(m_mutex); // 加锁保护
return empty_core();
};
T *back(void) {
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> lock(m_mutex); // 加锁保护
p_head->size = 0;
p_head->head = 0;
p_head->tail = 0;
};
};
#endif