156 lines
3.7 KiB
C++
156 lines
3.7 KiB
C++
/************************************************
|
||
* 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 |