aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/CnmSynchronizedCache.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/CnmSynchronizedCache.cs747
1 files changed, 747 insertions, 0 deletions
diff --git a/OpenSim/Framework/CnmSynchronizedCache.cs b/OpenSim/Framework/CnmSynchronizedCache.cs
new file mode 100644
index 0000000..2bafbe9
--- /dev/null
+++ b/OpenSim/Framework/CnmSynchronizedCache.cs
@@ -0,0 +1,747 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Threading;
32
33namespace OpenSim.Framework
34{
35 /// <summary>
36 /// Synchronized Cenome cache wrapper.
37 /// </summary>
38 /// <typeparam name="TKey">
39 /// The type of keys in the cache.
40 /// </typeparam>
41 /// <typeparam name="TValue">
42 /// The type of values in the cache.
43 /// </typeparam>
44 /// <remarks>
45 /// <para>
46 /// Enumerator will block other threads, until enumerator's <see cref="IDisposable.Dispose"/> method is called.
47 /// "foreach" statement is automatically calling it.
48 /// </para>
49 /// </remarks>
50 public class CnmSynchronizedCache<TKey, TValue> : ICnmCache<TKey, TValue>
51 {
52 /// <summary>
53 /// The cache object.
54 /// </summary>
55 private readonly ICnmCache<TKey, TValue> m_cache;
56
57 /// <summary>
58 /// Synchronization root.
59 /// </summary>
60 private readonly object m_syncRoot;
61
62 /// <summary>
63 /// Initializes a new instance of the <see cref="CnmSynchronizedCache{TKey,TValue}"/> class.
64 /// Initializes a new instance of the <see cref="CnmSynchronizedCache{TKey,TValue}"/> class.
65 /// </summary>
66 /// <param name="cache">
67 /// The cache.
68 /// </param>
69 private CnmSynchronizedCache(ICnmCache<TKey, TValue> cache)
70 {
71 m_cache = cache;
72 m_syncRoot = m_cache.SyncRoot;
73 }
74
75 /// <summary>
76 /// Returns a <see cref="ICnmCache{TKey,TValue}"/> wrapper that is synchronized (thread safe).
77 /// </summary>
78 /// <param name="cache">
79 /// The <see cref="ICnmCache{TKey,TValue}"/> to synchronize.
80 /// </param>
81 /// <returns>
82 /// A <see cref="ICnmCache{TKey,TValue}"/> wrapper that is synchronized (thread safe).
83 /// </returns>
84 /// <exception cref="ArgumentNullException">
85 /// <paramref name="cache"/>is null.
86 /// </exception>
87 public static ICnmCache<TKey, TValue> Synchronized(ICnmCache<TKey, TValue> cache)
88 {
89 if (cache == null)
90 throw new ArgumentNullException("cache");
91 return cache.IsSynchronized ? cache : new CnmSynchronizedCache<TKey, TValue>(cache);
92 }
93
94 #region Nested type: SynchronizedEnumerator
95
96 /// <summary>
97 /// Synchronized enumerator.
98 /// </summary>
99 private class SynchronizedEnumerator : IEnumerator<KeyValuePair<TKey, TValue>>
100 {
101 /// <summary>
102 /// Enumerator that is being synchronized.
103 /// </summary>
104 private readonly IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator;
105
106 /// <summary>
107 /// Synchronization root.
108 /// </summary>
109 private object m_syncRoot;
110
111 /// <summary>
112 /// Initializes a new instance of the <see cref="SynchronizedEnumerator"/> class.
113 /// </summary>
114 /// <param name="enumerator">
115 /// The enumerator that is being synchronized.
116 /// </param>
117 /// <param name="syncRoot">
118 /// The sync root.
119 /// </param>
120 public SynchronizedEnumerator(IEnumerator<KeyValuePair<TKey, TValue>> enumerator, object syncRoot)
121 {
122 m_syncRoot = syncRoot;
123 m_enumerator = enumerator;
124 Monitor.Enter(m_syncRoot);
125 }
126
127 /// <summary>
128 /// Finalizes an instance of the <see cref="SynchronizedEnumerator"/> class.
129 /// </summary>
130 ~SynchronizedEnumerator()
131 {
132 Dispose();
133 }
134
135 #region IEnumerator<KeyValuePair<TKey,TValue>> Members
136
137 /// <summary>
138 /// Gets the element in the collection at the current position of the enumerator.
139 /// </summary>
140 /// <returns>
141 /// The element in the collection at the current position of the enumerator.
142 /// </returns>
143 /// <exception cref="InvalidOperationException">
144 /// The enumerator has reach end of collection or <see cref="MoveNext"/> is not called.
145 /// </exception>
146 public KeyValuePair<TKey, TValue> Current
147 {
148 get { return m_enumerator.Current; }
149 }
150
151 /// <summary>
152 /// Gets the current element in the collection.
153 /// </summary>
154 /// <returns>
155 /// The current element in the collection.
156 /// </returns>
157 /// <exception cref="InvalidOperationException">
158 /// The enumerator is positioned before the first element of the collection or after the last element.
159 /// </exception><filterpriority>2</filterpriority>
160 object IEnumerator.Current
161 {
162 get { return Current; }
163 }
164
165 /// <summary>
166 /// Releases synchronization lock.
167 /// </summary>
168 public void Dispose()
169 {
170 if (m_syncRoot != null)
171 {
172 Monitor.Exit(m_syncRoot);
173 m_syncRoot = null;
174 }
175
176 m_enumerator.Dispose();
177 GC.SuppressFinalize(this);
178 }
179
180 /// <summary>
181 /// Advances the enumerator to the next element of the collection.
182 /// </summary>
183 /// <returns>
184 /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
185 /// </returns>
186 /// <exception cref="InvalidOperationException">
187 /// The collection was modified after the enumerator was created.
188 /// </exception>
189 public bool MoveNext()
190 {
191 return m_enumerator.MoveNext();
192 }
193
194 /// <summary>
195 /// Sets the enumerator to its initial position, which is before the first element in the collection.
196 /// </summary>
197 /// <exception cref="InvalidOperationException">
198 /// The collection was modified after the enumerator was created.
199 /// </exception>
200 public void Reset()
201 {
202 m_enumerator.Reset();
203 }
204
205 #endregion
206 }
207
208 #endregion
209
210 #region ICnmCache<TKey,TValue> Members
211
212 /// <summary>
213 /// Gets current count of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
214 /// </summary>
215 /// <remarks>
216 /// <para>
217 /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
218 /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
219 /// </para>
220 /// </remarks>
221 /// <seealso cref="ICnmCache{TKey,TValue}.MaxCount"/>
222 /// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
223 /// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
224 /// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
225 public int Count
226 {
227 get
228 {
229 lock (m_syncRoot)
230 {
231 return m_cache.Count;
232 }
233 }
234 }
235
236 /// <summary>
237 /// Gets or sets elements expiration time.
238 /// </summary>
239 /// <value>
240 /// Elements expiration time.
241 /// </value>
242 /// <remarks>
243 /// <para>
244 /// When element has been stored in <see cref="ICnmCache{TKey,TValue}"/> longer than <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/>
245 /// and it is not accessed through <see cref="ICnmCache{TKey,TValue}.TryGetValue"/> method or element's value is
246 /// not replaced by <see cref="ICnmCache{TKey,TValue}.Set"/> method, then it is automatically removed from the
247 /// <see cref="ICnmCache{TKey,TValue}"/>.
248 /// </para>
249 /// <para>
250 /// It is possible that <see cref="ICnmCache{TKey,TValue}"/> implementation removes element before it's expiration time,
251 /// because total size or count of elements stored to cache is larger than <see cref="ICnmCache{TKey,TValue}.MaxSize"/> or <see cref="ICnmCache{TKey,TValue}.MaxCount"/>.
252 /// </para>
253 /// <para>
254 /// It is also possible that element stays in cache longer than <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/>.
255 /// </para>
256 /// <para>
257 /// Calling <see cref="ICnmCache{TKey,TValue}.PurgeExpired"/> try to remove all elements that are expired.
258 /// </para>
259 /// <para>
260 /// To disable time limit in cache, set <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/> to <see cref="DateTime.MaxValue"/>.
261 /// </para>
262 /// </remarks>
263 /// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
264 /// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
265 /// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
266 /// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
267 /// <seealso cref="ICnmCache{TKey,TValue}.Count"/>
268 /// <seealso cref="ICnmCache{TKey,TValue}.MaxCount"/>
269 /// <seealso cref="ICnmCache{TKey,TValue}.MaxSize"/>
270 /// <seealso cref="ICnmCache{TKey,TValue}.Size"/>
271 public TimeSpan ExpirationTime
272 {
273 get
274 {
275 lock (m_syncRoot)
276 {
277 return m_cache.ExpirationTime;
278 }
279 }
280
281 set
282 {
283 lock (m_syncRoot)
284 {
285 m_cache.ExpirationTime = value;
286 }
287 }
288 }
289
290 /// <summary>
291 /// Gets a value indicating whether <see cref="ICnmCache{TKey,TValue}"/> is limiting count of elements.
292 /// </summary>
293 /// <value>
294 /// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> count of elements is limited;
295 /// otherwise, <see langword="false"/>.
296 /// </value>
297 /// <remarks>
298 /// <para>
299 /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
300 /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
301 /// </para>
302 /// </remarks>
303 /// <seealso cref="ICnmCache{TKey,TValue}.Count"/>
304 /// <seealso cref="ICnmCache{TKey,TValue}.MaxCount"/>
305 /// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
306 /// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
307 public bool IsCountLimited
308 {
309 get
310 {
311 lock (m_syncRoot)
312 {
313 return m_cache.IsCountLimited;
314 }
315 }
316 }
317
318 /// <summary>
319 /// Gets a value indicating whether <see cref="ICnmCache{TKey,TValue}"/> is limiting size of elements.
320 /// </summary>
321 /// <value>
322 /// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> total size of elements is limited;
323 /// otherwise, <see langword="false"/>.
324 /// </value>
325 /// <remarks>
326 /// <para>
327 /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
328 /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
329 /// </para>
330 /// </remarks>
331 /// <seealso cref="ICnmCache{TKey,TValue}.MaxElementSize"/>
332 /// <seealso cref="ICnmCache{TKey,TValue}.Size"/>
333 /// <seealso cref="ICnmCache{TKey,TValue}.MaxSize"/>
334 /// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
335 /// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
336 public bool IsSizeLimited
337 {
338 get
339 {
340 lock (m_syncRoot)
341 {
342 return m_cache.IsSizeLimited;
343 }
344 }
345 }
346
347 /// <summary>
348 /// Gets a value indicating whether or not access to the <see cref="ICnmCache{TKey,TValue}"/> is synchronized (thread safe).
349 /// </summary>
350 /// <value>
351 /// <see langword="true"/> if access to the <see cref="ICnmCache{TKey,TValue}"/> is synchronized (thread safe);
352 /// otherwise, <see langword="false"/>.
353 /// </value>
354 /// <remarks>
355 /// <para>
356 /// To get synchronized (thread safe) access to <see cref="ICnmCache{TKey,TValue}"/> object, use
357 /// <see cref="CnmSynchronizedCache{TKey,TValue}.Synchronized"/> in <see cref="CnmSynchronizedCache{TKey,TValue}"/> class
358 /// to retrieve synchronized wrapper for <see cref="ICnmCache{TKey,TValue}"/> object.
359 /// </para>
360 /// </remarks>
361 /// <seealso cref="ICnmCache{TKey,TValue}.SyncRoot"/>
362 /// <seealso cref="CnmSynchronizedCache{TKey,TValue}"/>
363 public bool IsSynchronized
364 {
365 get { return true; }
366 }
367
368 /// <summary>
369 /// Gets a value indicating whether elements stored to <see cref="ICnmCache{TKey,TValue}"/> have limited inactivity time.
370 /// </summary>
371 /// <value>
372 /// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> has a fixed total size of elements;
373 /// otherwise, <see langword="false"/>.
374 /// </value>
375 /// <remarks>
376 /// If <see cref="ICnmCache{TKey,TValue}"/> have limited inactivity time and element is not accessed through <see cref="ICnmCache{TKey,TValue}.Set"/>
377 /// or <see cref="ICnmCache{TKey,TValue}.TryGetValue"/> methods in <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/> , then element is automatically removed from
378 /// the cache. Depending on implementation of the <see cref="ICnmCache{TKey,TValue}"/>, some of the elements may
379 /// stay longer in cache.
380 /// </remarks>
381 /// <seealso cref="ICnmCache{TKey,TValue}.ExpirationTime"/>
382 /// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
383 /// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
384 /// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
385 public bool IsTimeLimited
386 {
387 get
388 {
389 lock (m_syncRoot)
390 {
391 return m_cache.IsTimeLimited;
392 }
393 }
394 }
395
396 /// <summary>
397 /// Gets or sets maximal allowed count of elements that can be stored to <see cref="ICnmCache{TKey,TValue}"/>.
398 /// </summary>
399 /// <value>
400 /// <see cref="int.MaxValue"/>, if <see cref="ICnmCache{TKey,TValue}"/> is not limited by count of elements;
401 /// otherwise maximal allowed count of elements.
402 /// </value>
403 /// <remarks>
404 /// <para>
405 /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
406 /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
407 /// </para>
408 /// </remarks>
409 public int MaxCount
410 {
411 get
412 {
413 lock (m_syncRoot)
414 {
415 return m_cache.MaxCount;
416 }
417 }
418
419 set
420 {
421 lock (m_syncRoot)
422 {
423 m_cache.MaxCount = value;
424 }
425 }
426 }
427
428 /// <summary>
429 /// <para>Gets maximal allowed element size.</para>
430 /// </summary>
431 /// <value>
432 /// Maximal allowed element size.
433 /// </value>
434 /// <remarks>
435 /// <para>
436 /// If element's size is larger than <see cref="ICnmCache{TKey,TValue}.MaxElementSize"/>, then element is
437 /// not added to the <see cref="ICnmCache{TKey,TValue}"/>.
438 /// </para>
439 /// </remarks>
440 /// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
441 /// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
442 /// <seealso cref="ICnmCache{TKey,TValue}.Size"/>
443 /// <seealso cref="ICnmCache{TKey,TValue}.MaxSize"/>
444 public long MaxElementSize
445 {
446 get
447 {
448 lock (m_syncRoot)
449 {
450 return m_cache.MaxElementSize;
451 }
452 }
453 }
454
455 /// <summary>
456 /// Gets or sets maximal allowed total size for elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
457 /// </summary>
458 /// <value>
459 /// Maximal allowed total size for elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
460 /// </value>
461 /// <remarks>
462 /// <para>
463 /// Normally size is total bytes used by elements in the cache. But it can be any other suitable unit of measure.
464 /// </para>
465 /// <para>
466 /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
467 /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
468 /// </para>
469 /// </remarks>
470 /// <exception cref="ArgumentOutOfRangeException">value is less than 0.</exception>
471 /// <seealso cref="ICnmCache{TKey,TValue}.MaxElementSize"/>
472 /// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
473 /// <seealso cref="ICnmCache{TKey,TValue}.Size"/>
474 public long MaxSize
475 {
476 get
477 {
478 lock (m_syncRoot)
479 {
480 return m_cache.MaxSize;
481 }
482 }
483
484 set
485 {
486 lock (m_syncRoot)
487 {
488 m_cache.MaxSize = value;
489 }
490 }
491 }
492
493 /// <summary>
494 /// Gets total size of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
495 /// </summary>
496 /// <value>
497 /// Total size of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
498 /// </value>
499 /// <remarks>
500 /// <para>
501 /// Normally bytes, but can be any suitable unit of measure.
502 /// </para>
503 /// <para>
504 /// Element's size is given when element is added or replaced by <see cref="ICnmCache{TKey,TValue}.Set"/> method.
505 /// </para>
506 /// <para>
507 /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
508 /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
509 /// </para>
510 /// </remarks>
511 /// <seealso cref="ICnmCache{TKey,TValue}.MaxElementSize"/>
512 /// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
513 /// <seealso cref="ICnmCache{TKey,TValue}.MaxSize"/>
514 /// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
515 /// <seealso cref="ICnmCache{TKey,TValue}.ExpirationTime"/>
516 public long Size
517 {
518 get
519 {
520 lock (m_syncRoot)
521 {
522 return m_cache.Size;
523 }
524 }
525 }
526
527 /// <summary>
528 /// Gets an object that can be used to synchronize access to the <see cref="ICnmCache{TKey,TValue}"/>.
529 /// </summary>
530 /// <value>
531 /// An object that can be used to synchronize access to the <see cref="ICnmCache{TKey,TValue}"/>.
532 /// </value>
533 /// <remarks>
534 /// <para>
535 /// To get synchronized (thread safe) access to <see cref="ICnmCache{TKey,TValue}"/>, use <see cref="CnmSynchronizedCache{TKey,TValue}"/>
536 /// method <see cref="CnmSynchronizedCache{TKey,TValue}.Synchronized"/> to retrieve synchronized wrapper interface to
537 /// <see cref="ICnmCache{TKey,TValue}"/>.
538 /// </para>
539 /// </remarks>
540 /// <seealso cref="ICnmCache{TKey,TValue}.IsSynchronized"/>
541 /// <seealso cref="CnmSynchronizedCache{TKey,TValue}"/>
542 public object SyncRoot
543 {
544 get { return m_syncRoot; }
545 }
546
547 /// <summary>
548 /// Removes all elements from the <see cref="ICnmCache{TKey,TValue}"/>.
549 /// </summary>
550 /// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
551 /// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
552 /// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
553 /// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
554 /// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
555 public void Clear()
556 {
557 lock (m_syncRoot)
558 {
559 m_cache.Clear();
560 }
561 }
562
563 /// <summary>
564 /// Returns an enumerator that iterates through the elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
565 /// </summary>
566 /// <returns>
567 /// A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.
568 /// </returns>
569 /// <filterpriority>1</filterpriority>
570 public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
571 {
572 lock (m_syncRoot)
573 {
574 return new SynchronizedEnumerator(m_cache.GetEnumerator(), m_syncRoot);
575 }
576 }
577
578 /// <summary>
579 /// Purge expired elements from the <see cref="ICnmCache{TKey,TValue}"/>.
580 /// </summary>
581 /// <remarks>
582 /// <para>
583 /// Element becomes expired when last access time to it has been longer time than <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/>.
584 /// </para>
585 /// <para>
586 /// Depending on <see cref="ICnmCache{TKey,TValue}"/> implementation, some of expired elements
587 /// may stay longer than <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/> in the cache.
588 /// </para>
589 /// </remarks>
590 /// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
591 /// <seealso cref="ICnmCache{TKey,TValue}.ExpirationTime"/>
592 /// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
593 /// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
594 /// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
595 /// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
596 /// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
597 public void PurgeExpired()
598 {
599 lock (m_syncRoot)
600 {
601 m_cache.PurgeExpired();
602 }
603 }
604
605 /// <summary>
606 /// Removes element associated with <paramref name="key"/> from the <see cref="ICnmCache{TKey,TValue}"/>.
607 /// </summary>
608 /// <param name="key">
609 /// The key that is associated with element to remove from the <see cref="ICnmCache{TKey,TValue}"/>.
610 /// </param>
611 /// <exception cref="ArgumentNullException">
612 /// <paramref name="key"/>is <see langword="null"/>.
613 /// </exception>
614 /// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
615 /// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
616 /// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
617 /// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
618 /// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
619 public void Remove(TKey key)
620 {
621 lock (m_syncRoot)
622 {
623 m_cache.Remove(key);
624 }
625 }
626
627 /// <summary>
628 /// Removes elements that are associated with one of <paramref name="keys"/> from the <see cref="ICnmCache{TKey,TValue}"/>.
629 /// </summary>
630 /// <param name="keys">
631 /// The keys that are associated with elements to remove from the <see cref="ICnmCache{TKey,TValue}"/>.
632 /// </param>
633 /// <exception cref="ArgumentNullException">
634 /// <paramref name="keys"/>is <see langword="null"/>.
635 /// </exception>
636 /// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
637 /// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
638 /// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
639 /// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
640 /// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
641 public void RemoveRange(IEnumerable<TKey> keys)
642 {
643 lock (m_syncRoot)
644 {
645 m_cache.RemoveRange(keys);
646 }
647 }
648
649 /// <summary>
650 /// Add or replace an element with the provided <paramref name="key"/>, <paramref name="value"/> and <paramref name="size"/> to
651 /// <see cref="ICnmCache{TKey,TValue}"/>.
652 /// </summary>
653 /// <param name="key">
654 /// The object used as the key of the element. Can't be <see langword="null"/> reference.
655 /// </param>
656 /// <param name="value">
657 /// The object used as the value of the element to add or replace. <see langword="null"/> is allowed.
658 /// </param>
659 /// <param name="size">
660 /// The element's size. Normally bytes, but can be any suitable unit of measure.
661 /// </param>
662 /// <returns>
663 /// <see langword="true"/>if element has been added successfully to the <see cref="ICnmCache{TKey,TValue}"/>;
664 /// otherwise <see langword="false"/>.
665 /// </returns>
666 /// <exception cref="ArgumentNullException">
667 /// <paramref name="key"/>is <see langword="null"/>.
668 /// </exception>
669 /// <exception cref="ArgumentOutOfRangeException">
670 /// The element's <paramref name="size"/> is less than 0.
671 /// </exception>
672 /// <remarks>
673 /// <para>
674 /// If element's <paramref name="size"/> is larger than <see cref="ICnmCache{TKey,TValue}.MaxElementSize"/>, then element is
675 /// not added to the <see cref="ICnmCache{TKey,TValue}"/>, however - possible older element is
676 /// removed from the <see cref="ICnmCache{TKey,TValue}"/>.
677 /// </para>
678 /// <para>
679 /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
680 /// <see cref="ICnmCache{TKey,TValue}"/>will remove less recently used elements until it can fit an new element.
681 /// </para>
682 /// <para>
683 /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
684 /// <see cref="ICnmCache{TKey,TValue}"/>will remove less recently used elements until it can fit an new element.
685 /// </para>
686 /// </remarks>
687 /// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
688 /// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
689 /// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
690 /// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
691 /// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
692 /// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
693 /// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
694 public bool Set(TKey key, TValue value, long size)
695 {
696 lock (m_syncRoot)
697 {
698 return m_cache.Set(key, value, size);
699 }
700 }
701
702 /// <summary>
703 /// Gets the <paramref name="value"/> associated with the specified <paramref name="key"/>.
704 /// </summary>
705 /// <returns>
706 /// <see langword="true"/>if the <see cref="ICnmCache{TKey,TValue}"/> contains an element with
707 /// the specified key; otherwise, <see langword="false"/>.
708 /// </returns>
709 /// <param name="key">
710 /// The key whose <paramref name="value"/> to get.
711 /// </param>
712 /// <param name="value">
713 /// When this method returns, the value associated with the specified <paramref name="key"/>,
714 /// if the <paramref name="key"/> is found; otherwise, the
715 /// default value for the type of the <paramref name="value"/> parameter. This parameter is passed uninitialized.
716 /// </param>
717 /// <exception cref="ArgumentNullException">
718 /// <paramref name="key"/>is <see langword="null"/>.
719 /// </exception>
720 /// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
721 /// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
722 /// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
723 /// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
724 /// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
725 public bool TryGetValue(TKey key, out TValue value)
726 {
727 lock (m_syncRoot)
728 {
729 return m_cache.TryGetValue(key, out value);
730 }
731 }
732
733 /// <summary>
734 /// Returns an enumerator that iterates through the elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
735 /// </summary>
736 /// <returns>
737 /// A <see cref="IEnumerator"/> that can be used to iterate through the collection.
738 /// </returns>
739 /// <filterpriority>1</filterpriority>
740 IEnumerator IEnumerable.GetEnumerator()
741 {
742 return GetEnumerator();
743 }
744
745 #endregion
746 }
747}