clockwerk-opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 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 | |||
28 | using System; |
||
29 | using System.Collections; |
||
30 | using System.Collections.Generic; |
||
31 | using System.Threading; |
||
32 | |||
33 | namespace 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 | } |