Lru cache算法以及他的锁的问题
来源:互联网 发布:python单行注释 编辑:程序博客网 时间:2024/06/04 19:51
Lru cache codes:
1. use double linked list for LRU.
2. For the lock, Do we need to put Get operation in lock or not?
For example: 2.1. this.cache.TryGetValue(key,out entry); in method GetItem(...);
2.2. this.cache.ContainsKey(key) in method AddItem(...).
For 2.1. We have to put it witin lock. because in method TryGetValue(key, out entry), it is not thread-safe.
when one thread is get the entry index; then another thread delete the entry from entries, it is possible that entries[i] will return another entry value.
For 2.2. this.cache.ContainsKey(key), which is still not thread-safe. I put it out of lock{}, maybe there is some risk.(it is safe if we put it in lock{}).
// It is from https://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs
using System;using System.Collections.Generic;using System.Text;namespace LruCache_20170421{ public class LruCache<T> { public LruCache(int maxEntries) { if (maxEntries < 0) { throw new ArgumentOutOfRangeException("maxEntries", maxEntries, "maxEntries must be greater than or equal zero."); } this.maxEntries = maxEntries; } public bool LruCacheEnabled { get { return this.maxEntries > 0; } } public void AddItem(string key, T item) { if (!LruCacheEnabled) { throw new ApplicationException("LruCache is disabled."); } if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key", "Key cannot be null or empty."); } if (this.cache.ContainsKey(key)) { return; } lock (this.cache) { if (!this.cache.ContainsKey(key)) { if (this.cache.Count >= maxEntries) { RemoveOldestEntry(); } CacheEntry cacheEntry = new CacheEntry(); cacheEntry.Key = key; cacheEntry.Item = item; if (listEnd == null) { // set the first element in the list cacheEntry.Previous = null; cacheEntry.Next = null; listHead = cacheEntry; listEnd = cacheEntry; } else { AddElementToEnd(cacheEntry); } this.cache.Add(key, cacheEntry); } } } /// <summary> /// add the element to the end of the list /// </summary> /// <param name="cacheEntry"></param> private void AddElementToEnd(CacheEntry cacheEntry) { cacheEntry.Previous = listEnd; cacheEntry.Next = null; listEnd.Next = cacheEntry; listEnd = cacheEntry; } public T GetItem(string key, out bool cached) { if (!LruCacheEnabled) { throw new ApplicationException("LruCache is disabled."); } if (string.IsNullOrEmpty(key)) { //Logger.LogInformation("Key cannot be null or empty."); cached = false; return default(T); } T item = default(T); CacheEntry entry; lock (this.cache) { cached = this.cache.TryGetValue(key, out entry); if (cached) { item = entry.Item; #region move the element to the end of the list if (entry == listEnd) { return listEnd.Item; } if (entry == listHead) { // it is the head of the list // remove from the head listHead = entry.Next; listHead.Previous = null; } else // entry.Previous!=null { // remove from the list entry.Previous.Next = entry.Next; entry.Next.Previous = entry.Previous; } // add to the end AddElementToEnd(entry); #endregion } } return item; } #region Private /// <summary> /// Remove the end entry, which is oldest. /// </summary> private void RemoveOldestEntry() { if (listHead == null) // cache is null. { return; } // remove the element in list head CacheEntry entryToRemove = listHead; string keyToRemove = entryToRemove.Key; if (entryToRemove.Next != null) { entryToRemove.Next.Previous = null; } listHead = entryToRemove.Next; if (listEnd == entryToRemove) { listEnd = listHead; } this.cache.Remove(keyToRemove); } private readonly Dictionary<string, CacheEntry> cache = new Dictionary<string, CacheEntry>(); private readonly int maxEntries; private CacheEntry listHead; // element with the farest access time private CacheEntry listEnd; // element with the nearest access time private class CacheEntry { public string Key; public T Item; // double linked list public CacheEntry Previous; // point the element with the far access time public CacheEntry Next; // point the element with the near access time } #endregion }}
- Lru cache算法以及他的锁的问题
- LRU cache 算法的实现
- LRU cache的实现
- LRU Cache的实现
- LRU Cache的实现
- LRU Cache的实现
- 简单LRU算法实现的Cache(C++)
- 简单LRU算法实现的Cache(C++)
- 简单LRU算法实现的Cache(C++)
- cpu cache中LRU算法所需要的位数
- 简单LRU算法实现的Cache(C++)
- LRU的cache的实现
- LRU cache的简单实现
- LRU Cache的一种实现
- LRU cache的另一种实现
- LRU Cache的C++实现
- LRU Cache的简单实现
- Cache的设计和实现 LRU Cache
- poj3974_Palindrome_
- idea选择自己的包创建SSH项目
- Linux内核中断系列之中断的下半部(八)
- DAY6作业-百度登录框
- iOS获取类名NSStringFromClass 和 获取类NSClassFromString
- Lru cache算法以及他的锁的问题
- OpenStack安装与配置
- 动态规划为什么就是经典?
- BubbleSeekBar开源框架在andorid7.0无法适配的解决方案
- Node学习过程中遇到的一些小问题
- 使用Google的zxing组件识别二维码时,调整扫描区域和取景框的大小
- Easy 20 Same Tree(100)
- Android实现socket简单通讯总结
- mybatis自动生成代码git地址