发一段Cache集合的算法的代码。欢迎来看看有什么不足。

lostinetdotcom 2003-07-22 09:05:32
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
}
}



...全文
21 2 打赏 收藏 举报
写回复
2 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
lostinetdotcom 2003-07-22
  • 打赏
  • 举报
回复
using System;
using System.Threading;
using System.Collections;

namespace LostinetSample
{
class Class1
{
static Cache c=new Cache(TimeSpan.FromMilliseconds(1000));

[STAThread]
static void Main(string[] args)
{
for(int i=0;i<5;i++)
new Thread(new ThreadStart(new Job(i).Test)).Start();

new Job(9).Test();
}

static int tc=0;

public class Job
{
Random r=new Random(Guid.NewGuid().GetHashCode());
int id;
public Job(int i)
{
id=i;
}
public void Test()
{
int key=id;
for(int i=0;true;i++)
{
for(int k=0;k<r.Next(1000);k++)
{
c[r.NextDouble()]=1;
tc++;
}

if(i%40==0)
c.Insert(key,id,DateTime.Now+TimeSpan.FromMilliseconds(100+r.Next(1000)));

//if(i%50==49)c.Clear();

Thread.Sleep(20+r.Next(20));

Console.WriteLine(
string.Format("{0}\t{1}\t{2}\t{3}\t{4}",
c.Count,i,key,c[key],tc)
);
}
}
}
}
}



5555, 不小心放了20分。。。

我可怜的可用分啊~~
iamfeiyang 2003-07-22
  • 打赏
  • 举报
回复
楼主表伤心,20分何足道哉,可用分多了
相关推荐
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2003-07-22 09:05
社区公告

让您成为最强悍的C#开发者