zoukankan      html  css  js  c++  java
  • 自己封装的内存缓存类DotNet.Caches.Bytecached

    自己封装的内存缓存类DotNet.Caches.Bytecached

    Bytecached类是DSS.NET(Distributed State Service分布式状态服务)、DFS.NET(Distributed File System分布式文件系统)中的一个核心内存缓存类。

    在DSS.NET中用于保存和管理网站用户的Session数据。

    在DFS.NET中用于缓存使用频率较高的文件数据。

    特性:

    1、使用读写锁实现多线程并发控制

    2、多种过期数据清理方式

    3、精准的容量控制

    4、以最小的系统开销进行数据清理

    在一个对性能要求比较高的系统中,都需要用缓存来保存一临时数据。也许你正在寻找。。。

    View Code
    1 using System;
      2 using System.Collections.Generic;
      3 using System.Collections.ObjectModel;
      4 using System.ComponentModel;
      5 using System.Diagnostics;
      6 using System.Linq;
      7 using System.Threading;
      8 using DotNet.Utilities;
      9 
     10 namespace DotNet.Caches
     11 {
     12     public class Bytecached : IDisposable
     13     {
     14         private readonly IDictionary<string, byte[]> _caches;
     15         private readonly IDictionary<string, DateTime> _times;
     16         private long _size;
     17         private readonly ReaderWriterLock _readerWriterLock;
     18         private readonly BackgroundWorker _checkWorker;
     19 
     20         /// <summary>
     21         /// 最大容量/B
     22         /// </summary>
     23         public long MaxSize { get; set; }
     24 
     25         /// <summary>
     26         /// 是否启用缓存
     27         /// </summary>
     28         public bool Enabled { get; set; }
     29 
     30         /// <summary>
     31         /// 超时时间
     32         /// </summary>
     33         public TimeSpan Timeout { get; set; }
     34 
     35         /// <summary>
     36         /// 一次清理数量
     37         /// </summary>
     38         public int ClearCount { get; set; }
     39 
     40         /// <summary>
     41         /// 是否正在检查并清理超时缓存
     42         /// </summary>
     43         public bool Checking { get; private set; }
     44 
     45         /// <summary>
     46         /// 构造
     47         /// </summary>
     48         /// <param name="timingcheck">定时检查时间</param>
     49         public Bytecached(TimeSpan timingcheck = default(TimeSpan))
     50         {
     51             _caches = new Dictionary<string, byte[]>();
     52             _times = new Dictionary<string, DateTime>();
     53             _readerWriterLock = new ReaderWriterLock();
     54             MaxSize = 64*1024*1024;
     55             Enabled = true;
     56             ClearCount = 1;
     57 
     58             #region 检查并清理缓存
     59 
     60             if (timingcheck == default(TimeSpan))
     61             {
     62                 _checkWorker = new BackgroundWorker();
     63                 _checkWorker.DoWork += CheckWorker_DoWork;
     64             }
     65             else
     66             {
     67                 new Thread(obj =>
     68                 {
     69                     while (true)
     70                     {
     71                         var swt = new Stopwatch();
     72                         swt.Start();
     73                         CheckWorker_DoWork(null, null);
     74                         swt.Stop();
     75                         Thread.Sleep(timingcheck);
     76                     }
     77                 }) { IsBackground = true }.Start();
     78             }
     79 
     80             #endregion
     81         }
     82 
     83         public bool Set(string key, byte[] value)
     84         {
     85             return Set(key, value, DateTime.Now.Add(Timeout));
     86         }
     87 
     88         public bool Set(string key, byte[] value, DateTime effectiveDate)
     89         {
     90             if (!Enabled)
     91                 return false;
     92 
     93             _readerWriterLock.AcquireWriterLock(-1);
     94             try
     95             {
     96                 if (_caches.ContainsKey(key))
     97                 {
     98                     _size -= _caches[key].Length;
     99                     _caches[key] = value;
    100                     _times[key] = effectiveDate;
    101                 }
    102                 else
    103                 {
    104                     _caches.Add(key, value);
    105                     _times.Add(key, effectiveDate);
    106                 }
    107                 _size += value.Length;
    108             }
    109             catch(Exception er)
    110             {
    111                 LogUtil.WriteLog("Bytecached.Set", er);
    112                 return false;
    113             }
    114             finally
    115             {
    116                 _readerWriterLock.ReleaseWriterLock();
    117             }
    118 
    119             #region 检查并清理缓存
    120 
    121             try
    122             {
    123                 if (_checkWorker != null && !_checkWorker.IsBusy)
    124                 {
    125                     _checkWorker.RunWorkerAsync();
    126                 }
    127             }
    128             catch (Exception er)
    129             {
    130                 LogUtil.WriteLog("检查并清理缓存", er);
    131             }
    132 
    133             #endregion
    134 
    135             return true;
    136         }
    137 
    138         public byte[] Get(string key)
    139         {
    140             var expiry = Timeout == TimeSpan.Zero ? default(DateTime) : DateTime.Now.Add(Timeout);
    141             return Get(key, expiry);
    142         }
    143 
    144         public byte[] Get(string key, DateTime effectiveDate)
    145         {
    146             if (!Enabled)
    147                 return null;
    148 
    149             _readerWriterLock.AcquireReaderLock(-1);
    150             var exist = false;
    151             try
    152             {
    153                 byte[] v;
    154                 exist = _caches.TryGetValue(key, out v);
    155                 return v;
    156             }
    157             catch(Exception er)
    158             {
    159                 LogUtil.WriteLog("Bytecached.Get", er);
    160                 return null;
    161             }
    162             finally
    163             {
    164                 _readerWriterLock.ReleaseReaderLock();
    165                 if (exist && effectiveDate != default(DateTime))
    166                 {
    167                     #region 刷新缓存
    168 
    169                     new Thread(obj =>
    170                     {
    171                         var k = (string)((object[])obj)[0];
    172                         var edate = (DateTime)((object[])obj)[1];
    173                         while (!Refresh(k, edate))
    174                         {
    175                             Thread.Sleep(100);
    176                         }
    177                     }) { IsBackground = true }.Start(new object[]{key, effectiveDate});
    178 
    179                     #endregion
    180                 }
    181             }
    182         }
    183 
    184         public bool ContainsKey(string key)
    185         {
    186             if (!Enabled)
    187                 return false;
    188 
    189             _readerWriterLock.AcquireReaderLock(-1);
    190             try
    191             {
    192                 return _caches.ContainsKey(key);
    193             }
    194             catch(Exception er)
    195             {
    196                 LogUtil.WriteLog("Bytecached.ContainsKey", er);
    197                 return false;
    198             }
    199             finally
    200             {
    201                 _readerWriterLock.ReleaseReaderLock();
    202             }
    203         }
    204 
    205         public bool Refresh(string key)
    206         {
    207             return Timeout != TimeSpan.Zero && Refresh(key, DateTime.Now.Add(Timeout));
    208         }
    209 
    210         public bool Refresh(string key, DateTime effectiveDate)
    211         {
    212             _readerWriterLock.AcquireWriterLock(-1);
    213             try
    214             {
    215                 if (_caches.ContainsKey(key))
    216                 {
    217                     _times[key] = effectiveDate;
    218                 }
    219             }
    220             catch(Exception er)
    221             {
    222                 LogUtil.WriteLog("Bytecached.Refresh", er);
    223                 return false;
    224             }
    225             finally
    226             {
    227                 _readerWriterLock.ReleaseWriterLock();
    228             }
    229             return true;
    230         }
    231 
    232         public IList<string> Keys
    233         {
    234             get
    235             {
    236                 _readerWriterLock.AcquireReaderLock(-1);
    237                 try
    238                 {
    239                     return _caches.Keys.ToList();
    240                 }
    241                 catch (Exception er)
    242                 {
    243                     LogUtil.WriteLog("Bytecached.Keys", er);
    244                     return new List<string>();
    245                 }
    246                 finally
    247                 {
    248                     _readerWriterLock.ReleaseReaderLock();
    249                 }
    250             }
    251         }
    252 
    253         public ICollection<byte[]> Values
    254         {
    255             get
    256             {
    257                 _readerWriterLock.AcquireReaderLock(-1);
    258                 try
    259                 {
    260                     return _caches.Values;
    261                 }
    262                 catch (Exception er)
    263                 {
    264                     LogUtil.WriteLog("Bytecached.Keys", er);
    265                     return new List<byte[]>();
    266                 }
    267                 finally
    268                 {
    269                     _readerWriterLock.ReleaseReaderLock();
    270                 }
    271             }
    272         }
    273 
    274         public ICollection<DateTime> Times
    275         {
    276             get
    277             {
    278                 _readerWriterLock.AcquireReaderLock(-1);
    279                 try
    280                 {
    281                     return _times.Values;
    282                 }
    283                 catch (Exception er)
    284                 {
    285                     LogUtil.WriteLog("Bytecached.Times", er);
    286                     return new Collection<DateTime>();
    287                 }
    288                 finally
    289                 {
    290                     _readerWriterLock.ReleaseReaderLock();
    291                 }
    292             }
    293         }
    294 
    295         /// <summary>
    296         /// 移除指定数据
    297         /// </summary>
    298         /// <param name="key"></param>
    299         /// <returns></returns>
    300         public bool Remove(string key)
    301         {
    302             _readerWriterLock.AcquireWriterLock(-1);
    303             try
    304             {
    305                 if (_caches.ContainsKey(key))
    306                 {
    307                     _size -= _caches[key].Length;
    308                     _caches.Remove(key);
    309                     _times.Remove(key);
    310                 }
    311             }
    312             catch(Exception er)
    313             {
    314                 LogUtil.WriteLog("Bytecached.Remove_key", er);
    315                 return false;
    316             }
    317             finally
    318             {
    319                 _readerWriterLock.ReleaseWriterLock();
    320             }
    321             return true;
    322         }
    323 
    324         public void Clear()
    325         {
    326             _readerWriterLock.AcquireWriterLock(-1);
    327             try
    328             {
    329                 _size = 0;
    330                 _caches.Clear();
    331                 _times.Clear();
    332             }
    333             catch(Exception er)
    334             {
    335                 LogUtil.WriteLog("Bytecached.Clear", er);
    336             }
    337             finally
    338             {
    339                 _readerWriterLock.ReleaseWriterLock();
    340             }
    341         }
    342 
    343         private void CheckWorker_DoWork(object sender, DoWorkEventArgs e)
    344         {
    345             Checking = true;
    346             try
    347             {
    348                 bool clearSize;
    349                 bool collect;
    350                 IEnumerable<string> clearKeys;
    351                 var count = 0;
    352                 var swt = new Stopwatch();
    353                 var t = new Stopwatch();
    354 
    355                 #region 清理超时记录
    356 
    357                 _readerWriterLock.AcquireReaderLock(-1);
    358                 swt.Start();
    359                 try
    360                 {
    361                     clearKeys = from time in _times where time.Value <= DateTime.Now orderby time.Value select time.Key;
    362                 }
    363                 finally
    364                 {
    365                     _readerWriterLock.ReleaseReaderLock();
    366                     swt.Stop();
    367                 }
    368                 Thread.Sleep(10);
    369                 _readerWriterLock.AcquireWriterLock(-1);
    370                 t.Start();
    371                 swt.Reset();
    372                 swt.Start();
    373                 try
    374                 {
    375                     foreach (var clearKey in clearKeys)
    376                     {
    377                         if (t.ElapsedMilliseconds > 20)
    378                         {
    379                             _readerWriterLock.ReleaseWriterLock();
    380                             Thread.Sleep(10);
    381                             _readerWriterLock.AcquireWriterLock(-1);
    382                             t.Reset();
    383                         }
    384                         if (_caches.ContainsKey(clearKey))
    385                         {
    386                             _size -= _caches[clearKey].Length;
    387                             _caches.Remove(clearKey);
    388                             _times.Remove(clearKey);
    389                         }
    390                         count++;
    391                     }
    392                 }
    393                 finally
    394                 {
    395                     clearSize = _size >= MaxSize;
    396                     collect = count > 0 || clearSize;
    397                     _readerWriterLock.ReleaseWriterLock();
    398                     t.Stop();
    399                     swt.Stop();
    400                 }
    401 
    402                 #endregion
    403 
    404                 if (clearSize)
    405                 {
    406                     #region 清理超量记录
    407 
    408                     Thread.Sleep(10);
    409                     _readerWriterLock.AcquireReaderLock(-1);
    410                     swt.Reset();
    411                     swt.Start();
    412                     try
    413                     {
    414                         clearKeys = from time in _times orderby time.Value select time.Key;
    415                     }
    416                     finally
    417                     {
    418                         _readerWriterLock.ReleaseReaderLock();
    419                         swt.Stop();
    420                     }
    421                     Thread.Sleep(10);
    422                     _readerWriterLock.AcquireWriterLock(-1);
    423                     t.Reset();
    424                     t.Start();
    425                     swt.Reset();
    426                     swt.Start();
    427                     count = 0;
    428                     try
    429                     {
    430                         var i = 0;
    431                         foreach (var clearKey in clearKeys)
    432                         {
    433                             if (i == ClearCount - 1)
    434                                 i = 0;
    435                             if (i == 0 && _size < MaxSize)
    436                                 break;
    437                             if (t.ElapsedMilliseconds > 20)
    438                             {
    439                                 _readerWriterLock.ReleaseWriterLock();
    440                                 Thread.Sleep(10);
    441                                 _readerWriterLock.AcquireWriterLock(-1);
    442                                 t.Reset();
    443                             }
    444                             if (_caches.ContainsKey(clearKey))
    445                             {
    446                                 _size -= _caches[clearKey].Length;
    447                                 _caches.Remove(clearKey);
    448                                 _times.Remove(clearKey);
    449                             }
    450                             i++;
    451                             count++;
    452                         }
    453                     }
    454                     finally
    455                     {
    456                         _readerWriterLock.ReleaseWriterLock();
    457                         t.Stop();
    458                         swt.Stop();
    459                     }
    460 
    461                     #endregion
    462                 }
    463 
    464                 if (collect)
    465                 {
    466                     ThreadPool.QueueUserWorkItem(obj => GC.Collect());
    467                 }
    468             }
    469             finally
    470             {
    471                 Checking = false;
    472             }
    473         }
    474 
    475         public int Count
    476         {
    477             get
    478             {
    479                 _readerWriterLock.AcquireReaderLock(-1);
    480                 try
    481                 {
    482                     return _caches.Count;
    483                 }
    484                 catch(Exception er)
    485                 {
    486                     LogUtil.WriteLog("Bytecached.Count", er);
    487                     return 0;
    488                 }
    489                 finally
    490                 {
    491                     _readerWriterLock.ReleaseReaderLock();
    492                 }
    493             }
    494         }
    495 
    496         public long Size
    497         {
    498             get
    499             {
    500                 _readerWriterLock.AcquireReaderLock(-1);
    501                 try
    502                 {
    503                     return _size;
    504                 }
    505                 catch (Exception er)
    506                 {
    507                     LogUtil.WriteLog("Bytecached.Size", er);
    508                     return 0;
    509                 }
    510                 finally
    511                 {
    512                     _readerWriterLock.ReleaseReaderLock();
    513                 }
    514             }
    515         }
    516 
    517         public object[][] List
    518         {
    519             get
    520             {
    521                 _readerWriterLock.AcquireReaderLock(-1);
    522                 try
    523                 {
    524                     return _caches.Select(obj => new object[] { obj.Key, obj.Value.Length, _times[obj.Key] }).ToArray();
    525                 }
    526                 catch (Exception er)
    527                 {
    528                     LogUtil.WriteLog("Bytecached.List", er);
    529                     return new object[3][];
    530                 }
    531                 finally
    532                 {
    533                     _readerWriterLock.ReleaseReaderLock();
    534                 }
    535             }
    536         }
    537 
    538         public void Dispose()
    539         {
    540             Clear();
    541         }
    542     }
    543 }
     
     
     
    标签: DSS.NETDFS.NET
  • 相关阅读:
    SQL学习
    FOR XML PATH
    IOS学习网址
    weak nonatomic strong等介绍(ios)
    UVALive3045 POJ2000 ZOJ2345 Gold Coins
    UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
    UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
    UVA439 POJ2243 HDU1372 ZOJ1091 Knight Moves【BFS】
    UVA439 POJ2243 HDU1372 ZOJ1091 Knight Moves【BFS】
    UVA10905 Children's Game
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3031990.html
Copyright © 2011-2022 走看看