自己封装的内存缓存类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.NET , DFS.NET
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于自己封装的内存缓存类DotNet.Caches.Bytecached的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did46062