shuiping150 пре 1 дан
родитељ
комит
05315cba0a
1 измењених фајлова са 200 додато и 0 уклоњено
  1. 200 0
      JLHHJSvr/LJFrameWork/ljlib.cache/LJCache.cs

+ 200 - 0
JLHHJSvr/LJFrameWork/ljlib.cache/LJCache.cs

@@ -0,0 +1,200 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Threading;
+using LJLib.D;
+
+namespace LJLib
+{
+    /// <summary>
+    /// 缓存,超时自动清除,线程安全
+    /// </summary>
+    public sealed class LJCache<TKey, TValue> : Dictionary<TKey, TValue>
+    {
+        /// <summary>
+        /// 自动延长分钟数
+        /// </summary>
+        public double DefaultAddMinutes
+        {
+            get { return _defaultAddMinutes;}
+            set { _defaultAddMinutes = value; }
+        }
+
+        /// <summary>
+        /// 添加键值对, 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="minutes">超时分钟数</param>
+        public void Add(TKey key, TValue value, double minutes)
+        {
+            var deadline = DateTime.Now.AddMinutes(minutes);
+            Add(key, value, deadline);
+        }
+
+        /// <summary>
+        /// 添加永久对象或者按默认时间添加
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        public new void Add(TKey key, TValue value)
+        {
+            Add(key, value, _defaultAddMinutes);
+        }
+
+        public new TValue this[TKey key]
+        {
+            get
+            {
+                lock (syncRoot)
+                {
+                    SetDeadLine(key, DateTime.Now.AddMinutes(DefaultAddMinutes));
+                    return base[key];
+                }
+            }
+            set
+            {
+                lock (syncRoot)
+                {
+                    SetDeadLine(key, DateTime.Now.AddMinutes(DefaultAddMinutes));
+                    base[key] = value;
+                }
+            }
+        }
+
+        public new bool ContainsKey(TKey key)
+        {
+            lock (syncRoot)
+            {
+                var rslt = base.ContainsKey(key);
+                if (rslt)
+                {
+                    SetDeadLine(key, DateTime.Now.AddMinutes(DefaultAddMinutes));
+                }
+                return rslt;
+            }
+        }
+
+
+        #region 稀有成员实现逻辑
+
+        /// <summary>
+        /// 添加键值对,设置超时时间
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="deadline">超时时间</param>
+        private void Add(TKey key, TValue value, DateTime deadline)
+        {
+            lock (syncRoot)
+            {
+                base[key] = value;
+                SetDeadLine(key, deadline);
+            }
+        }
+
+        /// <summary>
+        /// 手动设置超时时间
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="deadline"></param>
+        /// <returns></returns>
+        private void SetDeadLine(TKey key, DateTime deadline)
+        {
+            lock (syncRoot)
+            {
+                deadline = deadline.AddMilliseconds(-deadline.Millisecond);
+
+                if (_deadlines == null)
+                {
+                    _deadlines = new Dictionary<TKey, DateTime>();
+                    _ix_keys = new SortedList<DateTime, HashSet<TKey>>();
+                }
+
+                if (_deadlines.ContainsKey(key))
+                {
+                    var olddt = _deadlines[key];
+                    _ix_keys[olddt].Remove(key);
+                    if (_ix_keys[olddt].Count == 0)
+                    {
+                        _ix_keys.Remove(olddt);
+                    }
+                }
+
+                _deadlines[key] = deadline;
+                if (!_ix_keys.ContainsKey(deadline))
+                {
+                    _ix_keys[deadline] = new HashSet<TKey>();
+                }
+                if (!_ix_keys[deadline].Contains(key))
+                {
+                    _ix_keys[deadline].Add(key);
+                }
+
+                if (_timer == null)
+                {
+                    _timer = new Timer((state) =>
+                    {
+                        try
+                        {
+                            //DebugHelper.GetTotalMemory("LJCache.Remove.开始");
+                            lock (syncRoot)
+                            {
+                                var dtNow = DateTime.Now;
+                                List<DateTime> dts = new List<DateTime>();
+                                for (int i = 0; _ix_keys != null && i < _ix_keys.Keys.Count && _ix_keys.Keys[i] <= dtNow; i++)
+                                {
+                                    dts.Add(_ix_keys.Keys[i]);
+                                    foreach (var oldkey in _ix_keys.Values[i])
+                                    {
+                                        _deadlines.Remove(oldkey);
+                                        base.Remove(oldkey);
+                                    }
+                                }
+                                foreach (var dt in dts)
+                                {
+                                    _ix_keys.Remove(dt);
+                                }
+                            }
+                            //DebugHelper.GetTotalMemory("LJCache.Remove.结束");
+                        }
+                        catch (Exception ex)
+                        {
+                            Trace.Write(ex);
+                        }
+                    }, null, 1000, 1000);
+                }   
+            }
+        }
+
+        /// <summary>
+        /// 线路同步对象
+        /// </summary>
+        private object syncRoot = new object();
+
+        /// <summary>
+        /// 缓存清除定时器
+        /// </summary>
+        private Timer _timer;
+
+        /// <summary>
+        /// 各键值对的销毁时间
+        /// </summary>
+        private Dictionary<TKey, DateTime> _deadlines;
+        /// <summary>
+        /// 按时间顺序过期
+        /// </summary>
+        private SortedList<DateTime, HashSet<TKey>> _ix_keys;
+
+        /// <summary>
+        /// 自动延长分钟数
+        /// </summary>
+        private double _defaultAddMinutes = 5;
+
+        public LJCache(IEqualityComparer<TKey> comparer) : base(comparer) { }
+
+        public LJCache() : base() { }
+
+        #endregion
+    }
+}