/************************************************ * 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 #include #include #include #include #include const short KEY_LEN = 48; template class CMemMap { private: // 使用固定大小的数组替代动态字符串 struct FixedKey { char data[KEY_LEN]; FixedKey() { std::memset(data, 0, KEY_LEN); } FixedKey(const std::string_view& str) { std::memset(data, 0, KEY_LEN); if (!str.empty()) { size_t copy_len = std::min(str.size(), static_cast(KEY_LEN - 1)); std::memcpy(data, str.data(), copy_len); } } bool operator==(const FixedKey& other) const { return std::memcmp(data, other.data, KEY_LEN) == 0; } bool operator==(const std::string_view& str) const { if (str.size() >= KEY_LEN) return false; return std::memcmp(data, str.data(), str.size()) == 0 && (str.size() == KEY_LEN - 1 || data[str.size()] == 0); } std::string_view toStringView() const { return std::string_view(data, std::strlen(data)); } struct Hasher { std::size_t operator()(const FixedKey& key) const { // 简单的哈希函数,针对固定长度数组优化 std::size_t hash = 5381; for (size_t i = 0; i < KEY_LEN && key.data[i] != 0; ++i) { hash = ((hash << 5) + hash) + key.data[i]; } return hash; } }; }; typedef struct { unsigned int maxsize; unsigned int size; unsigned int next; } HEAD; typedef struct { FixedKey key; // 使用 FixedKey 替代 char[KEY_LEN] TValue value; } SM_DAT; private: HEAD* p_head = nullptr; SM_DAT* p_ptr = nullptr; // 使用共享锁提高读性能 mutable std::shared_mutex m_data_mutex; // 使用 unordered_map 加速查找 std::unordered_map m_key_index; mutable std::shared_mutex m_index_mutex; // 线程本地缓存 struct ThreadCache { FixedKey key; unsigned int index = 0; bool valid = false; }; static thread_local ThreadCache s_thread_cache; // 字符串转换优化 template typename std::enable_if::value, FixedKey>::type toFixedKey(const TKey& tkey) const { std::ostringstream oss; oss << tkey; return FixedKey(oss.str()); } template typename std::enable_if::value, FixedKey>::type toFixedKey(const TKey& tkey) const { return FixedKey(tkey); } // 初始化哈希索引 void buildIndex() { std::unique_lock lock(m_index_mutex); m_key_index.clear(); if (!p_ptr) return; for (unsigned int i = 0; i < p_head->size; ++i) { m_key_index[p_ptr[i].key] = i; } } // 查找优化版本 int findIndexOptimized(const FixedKey& key) { // 1. 检查线程本地缓存 if (s_thread_cache.valid && s_thread_cache.key == key) { return static_cast(s_thread_cache.index); } // 2. 在哈希表中查找 { std::shared_lock lock(m_index_mutex); auto it = m_key_index.find(key); if (it != m_key_index.end()) { s_thread_cache.key = key; s_thread_cache.index = it->second; s_thread_cache.valid = true; return static_cast(it->second); } } return -1; } // 回退到线性查找 int findIndexFallback(const FixedKey& key) { for (unsigned int i = 0; i < p_head->size; ++i) { if (p_ptr[i].key == key) { // 更新索引 { std::unique_lock lock(m_index_mutex); m_key_index[key] = i; } s_thread_cache.key = key; s_thread_cache.index = i; s_thread_cache.valid = true; return static_cast(i); } } return -1; } void init(const std::string& tableName) { char* ptr = static_cast(GlobMem::GetInstancePtr()->GetTablePtr(tableName)); if (ptr == nullptr) { p_ptr = nullptr; p_head = nullptr; return; } p_head = reinterpret_cast(ptr); p_ptr = reinterpret_cast(ptr + sizeof(HEAD)); // 构建索引 buildIndex(); } public: CMemMap(const std::string& tableName) { this->init(tableName); } CMemMap(const std::string& tableName, unsigned int maxsize) { this->init(tableName); if (p_head) { p_head->maxsize = maxsize; if (p_head->size > p_head->maxsize) { p_head->size = p_head->maxsize; } { std::unique_lock lock(m_data_mutex); if (p_head->next >= p_head->maxsize) { p_head->next = p_head->maxsize; } p_head->next = p_head->next % p_head->maxsize; } // 重建索引 buildIndex(); } } ~CMemMap() = default; // 禁用复制 CMemMap(const CMemMap&) = delete; CMemMap& operator=(const CMemMap&) = delete; // 移动语义 CMemMap(CMemMap&& other) noexcept : p_head(other.p_head) , p_ptr(other.p_ptr) , m_key_index(std::move(other.m_key_index)) { other.p_head = nullptr; other.p_ptr = nullptr; } CMemMap& operator=(CMemMap&& other) noexcept { if (this != &other) { p_head = other.p_head; p_ptr = other.p_ptr; m_key_index = std::move(other.m_key_index); other.p_head = nullptr; other.p_ptr = nullptr; } return *this; } // 查找键是否存在 bool find(const TKey& tkey) { FixedKey key = toFixedKey(tkey); if (!p_ptr) return false; std::shared_lock lock(m_data_mutex); int idx = findIndexOptimized(key); if (idx >= 0) return true; // 哈希表中未找到,尝试线性查找 idx = findIndexFallback(key); return idx >= 0; } // 通过键获取值 TValue* operator[](const TKey& tkey) { FixedKey key = toFixedKey(tkey); if (!p_ptr) return nullptr; std::shared_lock lock(m_data_mutex); int idx = findIndexOptimized(key); if (idx < 0) { idx = findIndexFallback(key); } if (idx >= 0) { return &p_ptr[idx].value; } return nullptr; } // 插入键值对 bool insert(const TKey& tkey, const TValue& tvalue) { FixedKey key = toFixedKey(tkey); if (!p_ptr) return false; std::unique_lock lock(m_data_mutex); // 查找键是否存在 int idx = findIndexOptimized(key); if (idx < 0) { idx = findIndexFallback(key); } if (idx >= 0) { // 更新现有值 p_ptr[idx].value = tvalue; // 更新线程缓存 s_thread_cache.key = key; s_thread_cache.index = static_cast(idx); s_thread_cache.valid = true; return true; } // 键不存在,需要插入 if (p_head->size >= p_head->maxsize) { // 缓存已满,需要替换 unsigned int replace_index = p_head->next; // 从哈希表中移除旧键 { std::unique_lock index_lock(m_index_mutex); m_key_index.erase(p_ptr[replace_index].key); } // 清除线程缓存 if (s_thread_cache.valid && s_thread_cache.index == replace_index) { s_thread_cache.valid = false; } } else { p_head->size++; } // 执行插入 unsigned int insert_index = p_head->next; // 复制键值 p_ptr[insert_index].key = key; p_ptr[insert_index].value = tvalue; // 更新元数据 p_head->next = (p_head->next + 1) % p_head->maxsize; // 更新哈希表 { std::unique_lock index_lock(m_index_mutex); m_key_index[key] = insert_index; } // 更新线程缓存 s_thread_cache.key = key; s_thread_cache.index = insert_index; s_thread_cache.valid = true; return true; } // 指针版本 bool insert(const TKey& tkey, const TValue* tvalue) { if (!tvalue) return false; return insert(tkey, *tvalue); } // 其他接口保持不变,但使用数组下标语法提高性能 TValue* getCur(void) { std::shared_lock lock(m_data_mutex); if (!p_ptr) return nullptr; long idx = index_cur(); if (idx < 0) return nullptr; return &p_ptr[idx].value; } long index_cur(void) const { if (!p_head || p_head->maxsize == 0) return -1; if (p_head->next == 0) { return static_cast(p_head->maxsize - 1); } else { return static_cast((p_head->next - 1) % p_head->maxsize); } } TValue* operator()(unsigned int i) { std::shared_lock lock(m_data_mutex); if (!p_ptr || i >= p_head->size) return nullptr; return &p_ptr[i].value; } std::string getKey(unsigned int i) { std::shared_lock lock(m_data_mutex); if (!p_ptr || i >= p_head->size) return ""; return std::string(p_ptr[i].key.data); } bool empty(void) const { if (!p_head) return true; std::shared_lock lock(m_data_mutex); return p_head->size == 0; } unsigned int size(void) const { if (!p_head) return 0; std::shared_lock lock(m_data_mutex); return p_head->size; } void clear(void) { if (!p_head) return; std::unique_lock data_lock(m_data_mutex); std::unique_lock index_lock(m_index_mutex); p_head->size = 0; p_head->next = 0; m_key_index.clear(); s_thread_cache.valid = false; } // 批量操作优化 template void forEach(Func func) { std::shared_lock lock(m_data_mutex); for (unsigned int i = 0; i < p_head->size; ++i) { func(p_ptr[i].key.toStringView(), p_ptr[i].value); } } }; // 初始化线程本地缓存 template thread_local typename CMemMap::ThreadCache CMemMap::s_thread_cache; #endif