eis/inc/zlib/MemMap.hpp

221 lines
5.3 KiB
C++

/************************************************
* Fixed element pointer position.
* The current pointer points to the latest element
* by means of a primary key value
*
* create zoufuzhou 20201001
* modify zoufuzhou 20251024 Initializable key memory
*
************************************************/
#ifndef _MEM_MAP_CACHE_HPP_
#define _MEM_MAP_CACHE_HPP_
#include <glob/GlobMem.h>
#include <mutex>
#include <tuple>
#include <typeinfo>
const short KEY_LEN = 48;
// TValue requires a fixed length structure
template <typename TKey, typename TValue> class CMemMap {
typedef struct {
unsigned int maxsize;
unsigned int size;
unsigned int next;
} HEAD;
typedef struct {
char key[KEY_LEN];
TValue value;
} SM_DAT;
private:
std::tuple<string, unsigned int> mt_lastkey;
private:
HEAD *p_head;
SM_DAT *p_ptr;
private:
std::mutex m_mutex;
private:
// std::string toString(const TKey &key) {
// std::ostringstream ostream;
// ostream.unsetf(std::ios::skipws);
// ostream << key;
// if (typeid(TKey) == typeid(string)) {
// return ostream.str();
// }
// std::istringstream istream(ostream.str());
// std::string value;
// istream >> value;
// return value;
// }
std::string toString(const TKey &key) const {
return toStringImpl(key, std::is_same<TKey, std::string>());
}
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 = (SM_DAT *)(ptr + sizeof(HEAD));
};
public:
// size does not need to be map get
CMemMap(const string &tableName) {
this->init(tableName);
// assert(p_head->maxsize>1);
};
// map insert need set cache maxsize
CMemMap(const string &tableName, unsigned int maxsize) {
// assert(maxsize>1);
this->init(tableName);
p_head->maxsize = maxsize;
if (p_head->size > p_head->maxsize) {
p_head->size = p_head->maxsize;
}
m_mutex.lock();
if (p_head->next > p_head->maxsize) {
p_head->next = p_head->maxsize;
}
p_head->next = p_head->next % p_head->maxsize;
m_mutex.unlock();
};
~CMemMap(){};
TValue *operator()(void) { return &p_ptr->value; };
TValue *getCur(void) { return &(p_ptr + this->index_cur())->value; };
long index_cur(void) {
if (p_head->next <= 0) {
return p_head->maxsize - 1;
} else {
return (p_head->next - 1) % p_head->maxsize;
}
}
TValue *operator()(unsigned int i) {
if (p_ptr == nullptr)
return nullptr;
return &(p_ptr + i)->value;
};
string getKey(unsigned int i) {
if (p_ptr == nullptr)
return nullptr;
return (p_ptr + i)->key;
};
bool find(const TKey &tkey) {
string key = this->toString(tkey);
if (key == "")
return nullptr;
if (p_ptr == nullptr)
return nullptr;
if (std::get<0>(this->mt_lastkey) == key) {
return &(p_ptr + std::get<1>(this->mt_lastkey))->value;
}
for (unsigned int i = 0; i < this->size(); i++) {
if (memcmp((p_ptr + i)->key, key.c_str(), key.length()) == 0 &&
key.length() < KEY_LEN && strlen((p_ptr + i)->key) == key.length()) {
this->mt_lastkey = std::make_tuple(key, i);
return true;
}
}
return false;
};
TValue *operator[](const TKey &tkey) {
string key = this->toString(tkey);
if (key == "")
return nullptr;
if (p_ptr == nullptr)
return nullptr;
if (std::get<0>(this->mt_lastkey) == key) {
return &(p_ptr + std::get<1>(this->mt_lastkey))->value;
}
for (unsigned int i = 0; i < this->size(); i++) {
if (memcmp((p_ptr + i)->key, key.c_str(), key.length()) == 0 &&
key.length() < KEY_LEN && strlen((p_ptr + i)->key) == key.length()) {
this->mt_lastkey = std::make_tuple(key, i);
return &(p_ptr + i)->value;
}
}
return nullptr;
};
void insert(const TKey &tkey, TValue *tvalue) {
string key = this->toString(tkey);
if (key == "")
return;
if (p_ptr == nullptr)
return;
m_mutex.lock();
TValue *tmp = this->operator[](tkey);
if (tmp != nullptr) {
memcpy(tmp, tvalue, sizeof(TValue));
} else {
if (p_head->size < p_head->maxsize) {
p_head->size++;
}
this->mt_lastkey = std::make_tuple(key, p_head->next);
memcpy(&(p_ptr + p_head->next)->value, tvalue, sizeof(TValue));
memset(&(p_ptr + p_head->next)->key, 0, sizeof(p_ptr->key));
int len = min(key.length(), sizeof(p_ptr->key));
memcpy(&(p_ptr + p_head->next)->key, key.c_str(), len);
p_head->next = (p_head->next + 1) % p_head->maxsize;
}
m_mutex.unlock();
};
bool empty(void) {
if (p_head == nullptr)
return 0;
return !p_head->size;
};
unsigned int size(void) {
if (p_head == nullptr)
return 0;
return p_head->size;
};
void clear(void) {
if (p_head == nullptr)
return;
p_head->size = 0;
p_head->next = 0;
};
private:
// 通用实现
std::string toStringImpl(const TKey &key, std::false_type) const {
std::ostringstream oss;
oss << key;
return oss.str();
}
// string特化实现
std::string toStringImpl(const std::string &key, std::true_type) const {
return key;
}
};
#endif