LRUCache.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Shawnlee.Common.Cache
{
public class LRUCache<TKey,TValue>
{
const int DEFAULT_CAPACITY = 255;

int _capacity;
ReaderWriterLockSlim _locker;
IDictionary<TKey, TValue> _dictionary;
LinkedList<TKey> _linkedList;

public LRUCache() : this(DEFAULT_CAPACITY) { }

public LRUCache(int capacity)
{
_locker = new ReaderWriterLockSlim();
_capacity = capacity > 0 ? capacity : DEFAULT_CAPACITY;
_dictionary = new Dictionary<TKey, TValue>();
_linkedList = new LinkedList<TKey>();
}

public void Set(TKey key, TValue value)
{
_locker.EnterWriteLock();
try
{
_dictionary[key] = value;
_linkedList.Remove(key);
_linkedList.AddFirst(key);
if (_linkedList.Count > _capacity)
{
_dictionary.Remove(_linkedList.Last.Value);
_linkedList.RemoveLast();
}
}
finally { _locker.ExitWriteLock(); }
}

public bool TryGet(TKey key, out TValue value)
{
_locker.EnterUpgradeableReadLock();
try
{
bool b = _dictionary.TryGetValue(key, out value);
if (b)
{
_locker.EnterWriteLock();
try
{
_linkedList.Remove(key);
_linkedList.AddFirst(key);
}
finally { _locker.ExitWriteLock(); }
}
return b;
}
catch { throw; }
finally { _locker.ExitUpgradeableReadLock(); }
}

public bool ContainsKey(TKey key)
{
_locker.EnterReadLock();
try
{
return _dictionary.ContainsKey(key);
}
finally { _locker.ExitReadLock(); }
}

public int Count
{
get
{
_locker.EnterReadLock();
try
{
return _dictionary.Count;
}
finally { _locker.ExitReadLock(); }
}
}

public int Capacity
{
get
{
_locker.EnterReadLock();
try
{
return _capacity;
}
finally { _locker.ExitReadLock(); }
}
set
{
_locker.EnterUpgradeableReadLock();
try
{
if (value > 0 && _capacity != value)
{
_locker.EnterWriteLock();
try
{
_capacity = value;
while (_linkedList.Count > _capacity)
{
_linkedList.RemoveLast();
}
}
finally { _locker.ExitWriteLock(); }
}
}
finally { _locker.ExitUpgradeableReadLock(); }
}
}

public ICollection<TKey> Keys
{
get
{
_locker.EnterReadLock();
try
{
return _dictionary.Keys;
}
finally { _locker.ExitReadLock(); }
}
}

public ICollection<TValue> Values
{
get
{
_locker.EnterReadLock();
try
{
return _dictionary.Values;
}
finally { _locker.ExitReadLock(); }
}
}
}
}

posted @ 2016-10-26 16:45  @vip_c  阅读(121)  评论(0编辑  收藏  举报