- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
C# 中是否有现成的 LFU 缓存?
最佳答案
Java 有大量的 LFU 缓存实现,应该很容易移植到 C#,例如:http://faq.javaranch.com/view?CachingStrategies
这个商业 .NET 库执行 LFU http://www.kellermansoftware.com/pc-38-2-net-caching-library.aspx
这个其他商业 .NET 库也执行 LFU:http://www.sharedcache.com/cms/
我相信还有其他人。
这是一个基本的 LFU 实现,用于 C# 老化,我刚刚敲了敲它,它并不完美,但它是一个很好的起点:注意:此实现不是线程安全的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LFU {
class LFUCache<TKey,TValue> {
Dictionary<TKey, LinkedListNode<CacheNode>> cache = new Dictionary<TKey, LinkedListNode<CacheNode>>();
LinkedList<CacheNode> lfuList = new LinkedList<CacheNode>();
class CacheNode {
public TKey Key { get; set; }
public TValue Data { get; set; }
public int UseCount { get; set; }
}
int size;
int age = 0;
int agePolicy;
public LFUCache(int size) : this(size, 1000) {
}
/// <summary>
///
/// </summary>
/// <param name="size"></param>
/// <param name="agePolicy">after this number of gets the cache will take 1 off all UseCounts, forcing old stuff to expire.</param>
public LFUCache(int size, int agePolicy) {
this.agePolicy = 1000;
this.size = size;
}
public void Add(TKey key, TValue val) {
TValue existing;
if (!TryGet(key, out existing)) {
var node = new CacheNode() {Key = key, Data = val, UseCount = 1};
if (lfuList.Count == size) {
cache.Remove(lfuList.First.Value.Key);
lfuList.RemoveFirst();
}
var insertionPoint = Nodes.LastOrDefault(n => n.Value.UseCount < 2);
LinkedListNode<CacheNode> inserted;
if (insertionPoint == null) {
inserted = lfuList.AddFirst(node);
} else {
inserted = lfuList.AddAfter(insertionPoint, node);
}
cache[key] = inserted;
}
}
IEnumerable<LinkedListNode<CacheNode>> Nodes {
get {
var node = lfuList.First;
while (node != null) {
yield return node;
node = node.Next;
}
}
}
IEnumerable<LinkedListNode<CacheNode>> IterateFrom(LinkedListNode<CacheNode> node) {
while (node != null) {
yield return node;
node = node.Next;
}
}
public TValue GetOrDefault(TKey key) {
TValue val;
TryGet(key, out val);
return val;
}
public bool TryGet(TKey key, out TValue val) {
age++;
if (age > agePolicy) {
age = 0;
foreach (var node in cache.Values) {
var v = node.Value;
v.UseCount--;
}
}
LinkedListNode<CacheNode> data;
bool success = false;
if (cache.TryGetValue(key, out data)) {
var cacheNode = data.Value;
val = cacheNode.Data;
cacheNode.UseCount++;
var insertionPoint = IterateFrom(data).Last(n => n.Value.UseCount <= cacheNode.UseCount);
if (insertionPoint != data) {
lfuList.Remove(data);
lfuList.AddAfter(insertionPoint, data);
}
} else {
val = default(TValue);
}
return success;
}
}
class Program {
public static void Assert(bool condition, string message) {
if (!condition) {
Console.WriteLine("Assert failed : " + message);
throw new ApplicationException("Test Failed");
}
}
public static void RunAllTests(Program prog){
foreach (var method in prog.GetType().GetMethods()) {
if (method.Name.StartsWith("Test")) {
try {
method.Invoke(prog, null);
Console.WriteLine("Test Passed: " + method.Name);
} catch (Exception) {
Console.WriteLine("Test Failed : " + method.Name);
}
}
}
}
public void TestItemShouldBeThereOnceInserted() {
var cache = new LFUCache<string, int>(3);
cache.Add("a", 1);
cache.Add("b", 2);
cache.Add("c", 3);
cache.Add("d", 4);
Assert(cache.GetOrDefault("a") == 0, "should get 0");
Assert(cache.GetOrDefault("b") == 2, "should get 2");
Assert(cache.GetOrDefault("c") == 3, "should get 3");
Assert(cache.GetOrDefault("d") == 4, "should get 4");
}
public void TestLFUShouldWorkAsExpected() {
var cache = new LFUCache<string, int>(3);
cache.Add("a", 1);
cache.Add("b", 2);
cache.Add("c", 3);
cache.GetOrDefault("a");
cache.GetOrDefault("a");
cache.GetOrDefault("b");
cache.Add("d", 4);
cache.Add("e", 5);
Assert(cache.GetOrDefault("a") == 1, "should get 1");
Assert(cache.GetOrDefault("b") == 2, "should get 0");
Assert(cache.GetOrDefault("c") == 0, "should get 0");
Assert(cache.GetOrDefault("d") == 0, "should get 4");
Assert(cache.GetOrDefault("e") == 5, "should get 5");
}
static void Main(string[] args) {
RunAllTests(new Program());
Console.ReadKey();
}
}
}
关于c# - C# 中的 LFU 缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/953212/
1.题目 请你为最不经常使用(LFU)缓存算法设计并实现数据结构。 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象 in
我正在尝试设计一个缓存服务器,它将存储数据库查询的查询和结果键,从而减轻它的负载。 它可能是这样的: if Cache.isSet(query): return Cache.get(qu
最不常用 (LFU) 是一种用于管理计算机内存的缓存算法。这种方法的标准特征涉及系统跟踪一个 block 在内存中被引用的次数。当缓存已满并需要更多空间时,系统将清除引用频率最低的项目。 用 Java
LRU 和 LFU 缓存实现有什么区别? 我知道LRU可以使用LinkedHashMap来实现。但如何实现LFU缓存呢? 最佳答案 让我们考虑缓存容量为 3 的恒定缓存请求流,如下所示: A, B,
这个问题已经有答案了: What is the difference between LRU and LFU (4 个回答) 已关闭 7 年前。 我在一次采访中被问到这个问题,他首先问了 LRU 和
我在网上发现 LFU 是一种堆栈算法,但是当我问我的讲师他说它患有 belady 异常,但我已经尝试了很多例子,但没有找到任何证据来证明这一点,所以有人可以告诉我是否可以真的患上了吗?还是堆栈算法?如
C# 中是否有现成的 LFU 缓存? 最佳答案 Java 有大量的 LFU 缓存实现,应该很容易移植到 C#,例如:http://faq.javaranch.com/view?CachingStrat
我正在使用具有 3 个实例的 Redis 4,一个主实例和两个副本实例。 使用 allkeys-lfu 策略将主实例配置为具有最大内存限制。 我想知道我是否应该将我的读取查询也转发给主实例以使 LFU
性能测试,在编写代码后,单元测试及性能测试是重要的验收点,好的性能测试可以让我们提前发现程序中存在的问题。 测试用例 在Rust中,测试通常有两部分,一部分是文档测试,一部分是模块测试。 通常我们
我一直试图找到一个很好的案例,其中 LFU 比 LRU 更好,但我不确定。 我设法做的(但不确定这是否是一个很好的例子)是当您有一个容量为 3 的缓存并且缓存请求为 4(如 A B C D)但 C 和
我在我的 springboot 应用程序中使用了 redis。内存策略是 lfu 并且想查看热键的统计信息。 一种方法是连接到redis并运行./redis-cli --hotkeys 但最好监控前
准备面试时,我遇到了一些事情,这让我质疑我对大 O 常数时间算法的理解。 LeetCode 上的一个问题要求创建 LFU 缓存问题的解决方案。 有3种实现方法: 构造器 - 输入:int 容量 得到
是否可以从 Redis 数据库中检索所有 LFU key ?如果是,请提供示例命令行建议。 感谢一百万,穆格拉比 最佳答案 您可以使用 OBJECT IDLETIME 获取读取或写入操作未请求 key
我正在使用 Redis 并在配置中设置了一个 allkeys-lfu 以用于逐出。 然而,有一个 key 我想确保永远不会被驱逐,我可以手动设置该 key 的“保护”,以便它在任何情况下都不会被驱逐,
当 redis 通过 spring boot (spring-boot-starter-data-redis) 用作缓存技术时,我看到很少有像 TTL 这样的属性可以在 application.pro
我是一名优秀的程序员,十分优秀!