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
|