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