一种简单的LRU cache设计 C++
最近在工作中需要用到LRU cache用作緩存來提高性能,經過查閱各種資料,了解了其運行的機制,如下:
LRU cache可以用于在內存中保持當前的熱點數據,下面實現一個有大小限制的lru cache,相關如下:
????1. 模板化;
????2. 利用std::unordered_map實現o(1)查找,利用std::list實現o(1)刪除 (雙鏈表+hash表);
????3. 用map保持key和結點在鏈表中的位置(iterator)
????4. 需要同時考慮如下情況:
????????put操作:?
?????????????(1) 如果當前key存在,則將對于的結點剪切到鏈表的頭部,同時更新哈希表中value的值;
?????????????(2) 如果當前key不存在于hash表中,且元素個數已經達到最大值,則刪除鏈表的最后一個結點,同時把新結點插入到鏈表的頭部,同時更新hash表(增加新節點和刪除舊結點表項);
????????get操作:
?????????????(1)檢查當前hash表中是否有該key,如果存在,則將該key對應的結點move到list的頭部,并同步獲取map的value;
?????????????(2)如果hash表中不存在該key,則返回false;
主要的代碼如下:
? ? void put(const key_t& key, const value_t& value) {
? ? ? ? if (cache_items_map_.count(key) > 0) { // find the key
? ? ? ? ? ? list_iterator_t iter = cache_items_map_[key];
? ? ? ? ? ? iter->second = value;
? ? ? ? ? ? cache_items_list_.splice(cache_items_list_.begin(), cache_items_list_, iter); // move to header
? ? ? ? } else {
? ? ? ? ? ? if (cache_items_list_.size() >= max_size_) {
? ? ? ? ? ? ? ? cache_items_map_.erase(cache_items_list_.back().first); ?// remove the last element from list
? ? ? ? ? ? ? ? cache_items_list_.pop_back(); // remove the last element in list
? ? ? ? ? ? }
? ? ? ? ? ? //insert new element to map and list
? ? ? ? ? ? cache_items_list_.push_front(key_value_pair_t(key, value));
? ? ? ? ? ? cache_items_map_[key] = cache_items_list_.begin();
? ? ? ? }
? ? }
? ? bool get(const key_t& key, value_t& value) {
? ? ? ? map_iterator_t it = cache_items_map_.find(key);
? ? ? ? if (it == cache_items_map_.end()) {
? ? ? ? ? ? return false;
? ? ? ? } else {
? ? ? ? ? ? cache_items_list_.splice(cache_items_list_.begin(), cache_items_list_, it->second);
? ? ? ? ? ? value = ?it->second->second;
? ? ? ? ? ? return true;
? ? ? ? }
? ? }
? ? std::list<key_value_pair_t> cache_items_list_;
? ? boost::unordered_map<key_t, list_iterator_t> cache_items_map_;
? ? int64_t max_size_;
經過測試,達到了預期的結果。
總結
以上是生活随笔為你收集整理的一种简单的LRU cache设计 C++的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Map集合遍历方式
- 下一篇: C++ 11 nullptr关键字