C++ LRU算法

LRU.h

cpp 复制代码
#pragma once
#include <cassert>
#include <functional>
#include <list>
#include <map>
#include <utility>

namespace cpv {
	/**
	 * A cache type that keeps up to given number of least recently used values.
	 *
	 * Notice:
	 * It's not thread safe, don't use it across threads without mutex.
	 */
	template <
		class Key,
		class Value,
		class List = std::list<std::pair<Key, Value>>,
		// use ordered map and std::less<> by default for heterogeneous lookup
		class Map = std::map<Key, typename List::iterator, std::less<>>>
	class LRUCache {
	public:
		/** Associate value with key, remove finally not used value if size is over */
		template <class TKey, class TValue>
		void set(TKey&& keyForMap, TKey&& keyForList, TValue&& value) {
			assert(keyForMap == keyForList);
			auto it = map_.find(keyForMap);
			if (it != map_.end()) {
				list_.erase(it->second);
				map_.erase(it);
			}
			list_.emplace_front(
				std::forward<TKey>(keyForList), std::forward<TValue>(value));
			map_.emplace(std::forward<TKey>(keyForMap), list_.begin());
			if (map_.size() > maxSize_) {
				map_.erase(list_.back().first);
				list_.pop_back();
			}
		}

		/** Associate value with key, remove finally not used value if size is over */
		template <class TKey, class TValue>
		void set(const TKey& key, TValue&& value) {
			set(TKey(key), TKey(key), std::forward<TValue>(value));
		}

		/** Associate value with key, remove finally not used value if size is over */
		void set(Key&& keyForMap, Key&& keyForList, Value&& value) {
			assert(keyForMap == keyForList);
			set<Key, Value>(std::move(keyForMap), std::move(keyForList), std::move(value));
		}

		/** Associate value with key, remove finally not used value if size is over */
		void set(const Key& key, Value&& value) {
			set<Key, Value>(Key(key), Key(key), std::move(value));
		}

		/** Get pointer of value associated with key or return nullptr */
		template <class TKey>
		Value* get(TKey&& key) & {
			auto it = map_.find(std::forward<TKey>(key));
			if (it == map_.end()) {
				return nullptr;
			} else {
				list_.splice(list_.begin(), list_, it->second);
				return &it->second->second;
			}
		}

		/** Get pointer of value associated with key or return nullptr */
		Value* get(const Key& key) & {
			return get<const Key&>(key);
		}

		/** Erase value associated with key, return whether key was exists */
		template <class TKey>
		bool erase(TKey&& key) {
			auto it = map_.find(std::forward<TKey>(key));
			if (it == map_.end()) {
				return false;
			} else {
				list_.erase(it->second);
				map_.erase(it);
				return true;
			}
		}

		/** Erase value associated with key, return whether key was exists */
		bool erase(const Key& key) {
			return erase<const Key&>(key);
		}

		/** Erase all values in cache */
		void clear() {
			list_.clear();
			map_.clear();
		}

		/** Get the number of values in cache */
		std::size_t size() const {
			return map_.size();
		}

		/** Get the maximum number of values allow to keep in cache */
		std::size_t maxSize() const {
			return maxSize_;
		}

		/** Return whether the cache is empty */
		bool empty() const {
			return map_.empty();
		}

		/** Construct with max number of values allow to keep in cache */
		LRUCache(std::size_t maxSize) :
			list_(),
			map_(),
			maxSize_(maxSize) { }

	private:
		List list_;
		Map map_;
		std::size_t maxSize_;
	};
}
cpp 复制代码
#include "LRU.h"
#include <assert>
#include <string>
void test() {
	cpv::LRUCache<int, std::string> cache(3);
	cache.set(1, "a");
	cache.set(2, "b");
	cache.set(3, "c");
	cache.set(100, "abc");
	std::string* result = cache.get(1);
	assert(result == nullptr);
}

GitHub - mohaps/lrucache11: A header only C++11 LRU Cache template class that allows you to define key, value and optionally the Map type. uses a double linked list and a std::unordered_map style container to provide fast insert, delete and update No dependencies other than the C++ standard library. This is a C++11 remake of my earlier LRUCache project (https://github.com/mohaps/lrucache) The goal was to create a fast LRUCache header only library and to avoid any dependencies like boost.


创作不易,小小的支持一下吧!

相关推荐
转调9 分钟前
每日一练:地下城游戏
开发语言·c++·算法·leetcode
不穿格子衬衫37 分钟前
常用排序算法(下)
c语言·开发语言·数据结构·算法·排序算法·八大排序
wdxylb44 分钟前
使用C++的OpenSSL 库实现 AES 加密和解密文件
开发语言·c++·算法
aqua35357423581 小时前
蓝桥杯-财务管理
java·c语言·数据结构·算法
CV金科1 小时前
蓝桥杯—STM32G431RBT6(IIC通信--EEPROM(AT24C02)存储器进行通信)
stm32·单片机·嵌入式硬件·算法·蓝桥杯
sewinger1 小时前
区间合并算法详解
算法
CSP126361 小时前
特别节目————集训总结
c++
XY.散人1 小时前
初识算法 · 滑动窗口(1)
算法
程序猿阿伟1 小时前
《C++游戏人工智能开发:开启智能游戏新纪元》
c++·人工智能·游戏
韬. .2 小时前
树和二叉树知识点大全及相关题目练习【数据结构】
数据结构·学习·算法