发一段Cache集合的算法的代码。欢迎来看看有什么不足。
namespace LostinetSample
{
using System;
using System.Collections;
using System.Threading;
using System.Timers;
/// <summary>
/// 表示其元素可以过期的字典集合
/// </summary>
public class Cache : IDictionary
{
class Entry
{
public Entry(object k,object v,long t,bool r)
{
key=k;
value=v;
eachticks=t;
reset=r;
}
//Cache的key
public object key;
//Cache的value
public object value;
//是否自动重新设置过期
public bool reset;
//相对当前的过期ticks
public long eachticks;
//绝对的过期ticks
public long timeoutticks;
}
ReaderWriterLock rwl=new ReaderWriterLock();
System.Timers.Timer timer;
Hashtable ht=new Hashtable();
TimeSpan tsd=TimeSpan.FromMilliseconds(10);
bool autors=true;
/// <summary>
/// 按默认的过期策略来初始化Cache
/// </summary>
public Cache()
{
timer=new System.Timers.Timer();
timer.BeginInit();
timer.Elapsed+=new ElapsedEventHandler(HandleElapsed);
timer.AutoReset=false;
timer.Enabled=false;
timer.EndInit();
}
/// <summary>
/// 使用指定的过期策略来初始化Cache
/// </summary>
public Cache(TimeSpan tsdefault):this()
{
tsd=ValidateTimeSpan(tsdefault);
}
/// <summary>
/// 使用指定的过期策略来初始化Cache
/// </summary>
public Cache(TimeSpan tsdefault,bool autoReset):this(tsdefault)
{
autors=autoReset;
}
static TimeSpan ValidateTimeSpan(TimeSpan ts)
{
if(ts.Ticks<=0)
throw(new ArgumentOutOfRangeException("ValidateTimeSpan failed"));
return ts;
}
long lastticks=0;
void SetTimeout(long ticks)
{
if(lastticks==0||ticks<lastticks)
{
lastticks=ticks;
if(timer.Enabled)timer.Stop();
TimeSpan ts=new DateTime(ticks)-DateTime.Now;
timer.Interval=Math.Max(1,ts.TotalMilliseconds);
timer.Start();
}
}
void HandleElapsed(object sender,ElapsedEventArgs args)
{
rwl.AcquireWriterLock(Timeout.Infinite);
try
{
lastticks=0;
ArrayList entries=new ArrayList();
long ticks=DateTime.Now.Ticks;
long nextticks=long.MaxValue;
foreach(Entry entry in ht.Values)
{
if(entry.timeoutticks<=ticks)
entries.Add(entry);
else
nextticks=Math.Min(nextticks,entry.timeoutticks);
}
if(nextticks!=long.MaxValue)
SetTimeout(nextticks);
foreach(Entry entry in entries)
{
ht.Remove(entry.key);
}
}
finally
{
rwl.ReleaseWriterLock();
}
}
void ResetEntryExpires(Entry e)
{
long dtticks=e.eachticks+DateTime.Now.Ticks;
e.timeoutticks=dtticks;
SetTimeout(dtticks);
}
Entry CreateEntry(object key,object value,TimeSpan ts,bool reset)
{
Entry e=new Entry(key,value,ts.Ticks,reset);
ResetEntryExpires(e);
return e;
}
object GetEntryValue(Entry e)
{
if(e.reset)ResetEntryExpires(e);
return e.value;
}
void SetEntryValue(Entry e,object value)
{
if(e.reset)ResetEntryExpires(e);
e.value=value;
}
/// <summary>
/// 设置或取得Cache中的值
/// </summary>
public object this[object key]
{
get
{
if(key==null)throw(new ArgumentNullException("key"));
rwl.AcquireReaderLock(Timeout.Infinite);
try
{
object o=ht[key];
if(o==null)return null;
Entry e=(Entry)o;
return GetEntryValue(e);
}
finally
{
rwl.ReleaseReaderLock();
}
}
set
{
Insert(key,value);
}
}
#region Insert..
/// <summary>
/// 按默认的过期策略添加元素
/// </summary>
public void Insert(object key,object value)
{
Insert(key,value,tsd);
}
/// <summary>
/// 添加在指定的时间间隔后过期的key/value,自动重设按默认设置
/// </summary>
public void Insert(object key,object value,TimeSpan ts)
{
Insert(key,value,ts,autors);
}
/// <summary>
/// 添加在指定的时间后过期的key/value
/// </summary>
public void Insert(object key,object value,DateTime dt)
{
Insert(key,value,dt-DateTime.Now,false);
}
/// <summary>
/// 添加在指定的时间间隔后过期的key/value,并且指定是否自动重设
/// </summary>
public void Insert(object key,object value,TimeSpan ts,bool autoReset)
{
if(key==null)throw(new ArgumentNullException("key"));
rwl.AcquireWriterLock(Timeout.Infinite);
try
{
object o=ht[key];
if(o==null)
ht[key]=CreateEntry(key,value,ts,autoReset);
else
SetEntryValue((Entry)o,value);
}
finally
{
rwl.ReleaseWriterLock();
}
}
#endregion
#region Add..
/// <summary>
/// 按默认的过期策略添加元素
/// </summary>
public void Add(object key,object value)
{
if(ht.Contains(key))throw(new ArgumentException("key"));
Insert(key,value);
}
/// <summary>
/// 添加在指定的时间后过期的key/value
/// </summary>
public void Add(object key,object value,DateTime dt)
{
if(ht.Contains(key))throw(new ArgumentException("key"));
Insert(key,value,dt);
}
/// <summary>
/// 添加在指定的时间间隔后过期的key/value,自动重设按默认设置
/// </summary>
public void Add(object key,object value,TimeSpan ts)
{
if(ht.Contains(key))throw(new ArgumentException("key"));
Insert(key,value,ts);
}
/// <summary>
/// 添加在指定的时间间隔后过期的key/value,并且指定是否自动重设
/// </summary>
public void Add(object key,object value,TimeSpan ts,bool autoReset)
{
if(ht.Contains(key))throw(new ArgumentException("key"));
Insert(key,value,ts,autoReset);
}
#endregion
#region Remove,Clear
/// <summary>
/// 删除指定的key
/// </summary>
public void Remove(object key)
{
rwl.AcquireWriterLock(Timeout.Infinite);
try
{
ht.Remove(key);
}
finally
{
rwl.ReleaseWriterLock();
}
}
/// <summary>
/// 清空所有元素
/// </summary>
public void Clear()
{
rwl.AcquireWriterLock(Timeout.Infinite);
try
{
ht.Clear();
}
finally
{
rwl.ReleaseWriterLock();
}
}
#endregion
/// <summary>
/// Cache中元素的Count
/// </summary>
public int Count
{
get
{
return ht.Count;
}
}
/// <summary>
/// 是否包含key
/// </summary>
public bool Contains(object key)
{
return ht.Contains(key);
}
/// <summary>
/// Values
/// </summary>
public ICollection Values
{
get
{
return ht.Values;
}
}
/// <summary>
/// Keys
/// </summary>
public ICollection Keys
{
get
{
return ht.Keys;
}
}
#region IDictionary 成员
bool IDictionary.IsReadOnly
{
get
{
return ht.IsReadOnly;
}
}
bool IDictionary.IsFixedSize
{
get
{
return ht.IsFixedSize;
}
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return ht.GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
ht.CopyTo(array,index);
}
bool ICollection.IsSynchronized
{
get
{
return ht.IsSynchronized;
}
}
object ICollection.SyncRoot
{
get
{
return ht.SyncRoot;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return ht.GetEnumerator();
}
#endregion
}
}