eis/inc/zlib/MemQueue.hpp

156 lines
3.7 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/************************************************
* 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