/************************************************ * 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 #include #include #include const short KEY_LEN = 48; // TValue requires a fixed length structure template 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 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()); } 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