using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

///


/// 数据缓存保存信息异步处理委托
///
delegate void EventSaveCache(object key, object value);
///
/// 对象缓存类
///
public class Cache
{
     private MappingContainer mContainer;
     ///
     /// 获取或设置当前缓存对象所在的关系映象容器
     ///
     public MappingContainer Container
     {
         get
         {
             return mContainer;
         }
         set
         {
             mContainer = value;
         }
     }
     ///
     /// 构造缓存对象
     ///
     public Cache()
     {
         //
         // TODO: 在此处添加构造函数逻辑
         //
     }
     ///
     /// 用于缓存数据的Hashtable
     ///
     protected System.Collections.Hashtable _Cache = new System.Collections.Hashtable();
     protected Object _LockObj = new object();
     ///
     /// 获取指定键值的对象
     ///
     /// 键值
     /// object
     public virtual object GetObject(object key)
     {
         if (_Cache.ContainsKey(key))
             return _Cache[key];
         return null;
     }
     ///
     /// 把对象按指定的键值保存到缓存中
     ///
     /// 键值
     /// 保存的对象
     public void SaveCaech(object key, object value)
     {
         EventSaveCache save = new EventSaveCache(SetCache);
         IAsyncResult ar = save.BeginInvoke(key, value, new System.AsyncCallback(Results), null);
     }
     private void Results(IAsyncResult ar)
     {
         EventSaveCache fd = (EventSaveCache)((AsyncResult)ar).AsyncDelegate;
         fd.EndInvoke(ar);
     }
     ///
     /// 把对象按指定的键值保存到缓存中
     ///
     /// 键值
     /// 保存的对象
     protected virtual void SetCache(object key, object value)
     {
         lock (_LockObj)
         {
             if (!_Cache.ContainsKey(key))
                 _Cache.Add(key, value);
         }
     }
     public int Count
     {
         get
         {
             return _Cache.Count;
         }
     }
     ///
     /// 在缓存中删除指定键值的对象
     ///
     /// 键值
     public virtual void DelObject(object key)
     {
         lock (_Cache.SyncRoot)
         {
             _Cache.Remove(key);
         }
     }
     ///
     /// 清除缓存中所有对象
     ///
     public virtual void Clear()
     {
         lock (_Cache.SyncRoot)
         {
             _Cache.Clear();
         }
     }
}

///


///针对一条记录操作命令的缓存类
///
public class CachePersistentCommand : Cache
{

     ///


     /// 把记录操作命令缓存到内存中
     ///
     /// 标识
     /// 值
     protected override void SetCache(object key, object value)
     {
         lock (_LockObj)
         {
             int count = 0;
             if (Container.Config.CommandsCache.ContainsKey(key))
                 count = (int)Container.Config.CommandsCache[key];
             System.Collections.IList _list;
             //如果缓存中已经存在这种命令的列表
             if (_Cache.ContainsKey(key))
             {
                 _list = (System.Collections.IList)_Cache[key];

                 if (count > 0)//命令的缓存总数
                 {
                     if (_list.Count < count)//缓存数据量少于缓存总数
                         _list.Add(value);
                 }
                 else
                 {
                     if (_list.Count < Container.Config.CommandBuffer)//缓存数小于组件的默认列表
                         _list.Add(value);
                 }
             }
             else//如果不存在列表
             {
                 if (count > 0 || Container.Config.CommandBuffer > 0)//如果组件允许对象缓存
                 {
                     _list = new System.Collections.ArrayList();
                     _list.Add(value);
                     _Cache.Add(key, _list);
                 }
             }
         }
     }
     ///


     /// 从缓存中获取相关命令对象
     ///
     /// 标识
     /// IPersistentCommand
     public override object GetObject(object key)
     {

         if (_Cache.Contains(key))//如果命令存在缓冲中
         {
             foreach (IPersistentCommand cmd in (System.Collections.IList)_Cache[key])
             {
                 if (!cmd.State)//命令是否可以过行锁定
                     if (cmd.Lock())//命令锁定
                         return cmd;
             }
         }
         return null;
     }

}