1
0

ICnmCache.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  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. using System;
  28. using System.Collections.Generic;
  29. namespace OpenSim.Framework
  30. {
  31. /// <summary>
  32. /// Represent generic cache to store key/value pairs (elements) limited by time, size and count of elements.
  33. /// </summary>
  34. /// <typeparam name="TKey">
  35. /// The type of keys in the cache.
  36. /// </typeparam>
  37. /// <typeparam name="TValue">
  38. /// The type of values in the cache.
  39. /// </typeparam>
  40. /// <remarks>
  41. /// <para>
  42. /// Cache store limitations:
  43. /// </para>
  44. /// <list type="table">
  45. /// <listheader>
  46. /// <term>Limitation</term>
  47. /// <description>Description</description>
  48. /// </listheader>
  49. /// <item>
  50. /// <term>Time</term>
  51. /// <description>
  52. /// Element that is not accessed through <see cref="TryGetValue"/> or <see cref="Set"/> in last <see cref="ExpirationTime"/> are
  53. /// removed from the cache automatically. Depending on implementation of the cache some of elements may stay longer in cache.
  54. /// <see cref="IsTimeLimited"/> returns <see langword="true"/>, if cache is limited by time.
  55. /// </description>
  56. /// </item>
  57. /// <item>
  58. /// <term>Count</term>
  59. /// <description>
  60. /// When adding an new element to cache that already have <see cref="MaxCount"/> of elements, cache will remove less recently
  61. /// used element(s) from the cache, until element fits to cache.
  62. /// <see cref="IsCountLimited"/> returns <see langword="true"/>, if cache is limiting element count.
  63. /// </description>
  64. /// </item>
  65. /// <item>
  66. /// <term>Size</term>
  67. /// <description>
  68. /// <description>
  69. /// When adding an new element to cache that already have <see cref="MaxSize"/> of elements, cache will remove less recently
  70. /// used element(s) from the cache, until element fits to cache.
  71. /// <see cref="IsSizeLimited"/> returns <see langword="true"/>, if cache is limiting total size of elements.
  72. /// Normally size is bytes used by element in the cache. But it can be any other suitable unit of measure.
  73. /// </description>
  74. /// </description>
  75. /// </item>
  76. /// </list>
  77. /// </remarks>
  78. public interface ICnmCache<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
  79. {
  80. /// <summary>
  81. /// Gets current count of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
  82. /// </summary>
  83. /// <remarks>
  84. /// <para>
  85. /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
  86. /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
  87. /// </para>
  88. /// </remarks>
  89. /// <seealso cref="MaxCount"/>
  90. /// <seealso cref="IsCountLimited"/>
  91. /// <seealso cref="IsSizeLimited"/>
  92. /// <seealso cref="IsTimeLimited"/>
  93. int Count { get; }
  94. /// <summary>
  95. /// Gets or sets elements expiration time.
  96. /// </summary>
  97. /// <value>
  98. /// Elements expiration time.
  99. /// </value>
  100. /// <remarks>
  101. /// <para>
  102. /// When element has been stored in <see cref="ICnmCache{TKey,TValue}"/> longer than <see cref="ExpirationTime"/>
  103. /// and it is not accessed through <see cref="TryGetValue"/> method or element's value is
  104. /// not replaced by <see cref="Set"/> method, then it is automatically removed from the
  105. /// <see cref="ICnmCache{TKey,TValue}"/>.
  106. /// </para>
  107. /// <para>
  108. /// It is possible that <see cref="ICnmCache{TKey,TValue}"/> implementation removes element before it's expiration time,
  109. /// because total size or count of elements stored to cache is larger than <see cref="MaxSize"/> or <see cref="MaxCount"/>.
  110. /// </para>
  111. /// <para>
  112. /// It is also possible that element stays in cache longer than <see cref="ExpirationTime"/>.
  113. /// </para>
  114. /// <para>
  115. /// Calling <see cref="PurgeExpired"/> try to remove all elements that are expired.
  116. /// </para>
  117. /// <para>
  118. /// To disable time limit in cache, set <see cref="ExpirationTime"/> to <see cref="DateTime.MaxValue"/>.
  119. /// </para>
  120. /// </remarks>
  121. /// <seealso cref="IsTimeLimited"/>
  122. /// <seealso cref="IsCountLimited"/>
  123. /// <seealso cref="IsSizeLimited"/>
  124. /// <seealso cref="PurgeExpired"/>
  125. /// <seealso cref="Count"/>
  126. /// <seealso cref="MaxCount"/>
  127. /// <seealso cref="MaxSize"/>
  128. /// <seealso cref="Size"/>
  129. TimeSpan ExpirationTime { get; set; }
  130. /// <summary>
  131. /// Gets a value indicating whether or not access to the <see cref="ICnmCache{TKey,TValue}"/> is synchronized (thread safe).
  132. /// </summary>
  133. /// <value>
  134. /// <see langword="true"/> if access to the <see cref="ICnmCache{TKey,TValue}"/> is synchronized (thread safe);
  135. /// otherwise, <see langword="false"/>.
  136. /// </value>
  137. /// <remarks>
  138. /// <para>
  139. /// To get synchronized (thread safe) access to <see cref="ICnmCache{TKey,TValue}"/> object, use
  140. /// <see cref="CnmSynchronizedCache{TKey,TValue}.Synchronized"/> in <see cref="CnmSynchronizedCache{TKey,TValue}"/> class
  141. /// to retrieve synchronized wrapper for <see cref="ICnmCache{TKey,TValue}"/> object.
  142. /// </para>
  143. /// </remarks>
  144. /// <seealso cref="SyncRoot"/>
  145. /// <seealso cref="CnmSynchronizedCache{TKey,TValue}"/>
  146. bool IsSynchronized { get; }
  147. /// <summary>
  148. /// Gets a value indicating whether <see cref="ICnmCache{TKey,TValue}"/> is limiting count of elements.
  149. /// </summary>
  150. /// <value>
  151. /// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> count of elements is limited;
  152. /// otherwise, <see langword="false"/>.
  153. /// </value>
  154. /// <remarks>
  155. /// <para>
  156. /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
  157. /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
  158. /// </para>
  159. /// </remarks>
  160. /// <seealso cref="Count"/>
  161. /// <seealso cref="MaxCount"/>
  162. /// <seealso cref="IsSizeLimited"/>
  163. /// <seealso cref="IsTimeLimited"/>
  164. bool IsCountLimited { get; }
  165. /// <summary>
  166. /// Gets a value indicating whether <see cref="ICnmCache{TKey,TValue}"/> is limiting size of elements.
  167. /// </summary>
  168. /// <value>
  169. /// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> total size of elements is limited;
  170. /// otherwise, <see langword="false"/>.
  171. /// </value>
  172. /// <remarks>
  173. /// <para>
  174. /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
  175. /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
  176. /// </para>
  177. /// </remarks>
  178. /// <seealso cref="MaxElementSize"/>
  179. /// <seealso cref="Size"/>
  180. /// <seealso cref="MaxSize"/>
  181. /// <seealso cref="IsCountLimited"/>
  182. /// <seealso cref="IsTimeLimited"/>
  183. bool IsSizeLimited { get; }
  184. /// <summary>
  185. /// Gets a value indicating whether elements stored to <see cref="ICnmCache{TKey,TValue}"/> have limited inactivity time.
  186. /// </summary>
  187. /// <value>
  188. /// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> has a fixed total size of elements;
  189. /// otherwise, <see langword="false"/>.
  190. /// </value>
  191. /// <remarks>
  192. /// If <see cref="ICnmCache{TKey,TValue}"/> have limited inactivity time and element is not accessed through <see cref="Set"/>
  193. /// or <see cref="TryGetValue"/> methods in <see cref="ExpirationTime"/> , then element is automatically removed from
  194. /// the cache. Depending on implementation of the <see cref="ICnmCache{TKey,TValue}"/>, some of the elements may
  195. /// stay longer in cache.
  196. /// </remarks>
  197. /// <seealso cref="ExpirationTime"/>
  198. /// <seealso cref="PurgeExpired"/>
  199. /// <seealso cref="IsCountLimited"/>
  200. /// <seealso cref="IsSizeLimited"/>
  201. bool IsTimeLimited { get; }
  202. /// <summary>
  203. /// Gets or sets maximal allowed count of elements that can be stored to <see cref="ICnmCache{TKey,TValue}"/>.
  204. /// </summary>
  205. /// <value>
  206. /// <see cref="int.MaxValue"/>, if <see cref="ICnmCache{TKey,TValue}"/> is not limited by count of elements;
  207. /// otherwise maximal allowed count of elements.
  208. /// </value>
  209. /// <remarks>
  210. /// <para>
  211. /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
  212. /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
  213. /// </para>
  214. /// </remarks>
  215. int MaxCount { get; set; }
  216. /// <summary>
  217. /// <para>Gets maximal allowed element size.</para>
  218. /// </summary>
  219. /// <value>
  220. /// Maximal allowed element size.
  221. /// </value>
  222. /// <remarks>
  223. /// <para>
  224. /// If element's size is larger than <see cref="MaxElementSize"/>, then element is
  225. /// not added to the <see cref="ICnmCache{TKey,TValue}"/>.
  226. /// </para>
  227. /// </remarks>
  228. /// <seealso cref="Set"/>
  229. /// <seealso cref="IsSizeLimited"/>
  230. /// <seealso cref="Size"/>
  231. /// <seealso cref="MaxSize"/>
  232. long MaxElementSize { get; }
  233. /// <summary>
  234. /// Gets or sets maximal allowed total size for elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
  235. /// </summary>
  236. /// <value>
  237. /// Maximal allowed total size for elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
  238. /// </value>
  239. /// <remarks>
  240. /// <para>
  241. /// Normally size is total bytes used by elements in the cache. But it can be any other suitable unit of measure.
  242. /// </para>
  243. /// <para>
  244. /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
  245. /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
  246. /// </para>
  247. /// </remarks>
  248. /// <exception cref="ArgumentOutOfRangeException">value is less than 0.</exception>
  249. /// <seealso cref="MaxElementSize"/>
  250. /// <seealso cref="IsSizeLimited"/>
  251. /// <seealso cref="Size"/>
  252. long MaxSize { get; set; }
  253. /// <summary>
  254. /// Gets total size of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
  255. /// </summary>
  256. /// <value>
  257. /// Total size of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
  258. /// </value>
  259. /// <remarks>
  260. /// <para>
  261. /// Normally bytes, but can be any suitable unit of measure.
  262. /// </para>
  263. /// <para>
  264. /// Element's size is given when element is added or replaced by <see cref="Set"/> method.
  265. /// </para>
  266. /// <para>
  267. /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
  268. /// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
  269. /// </para>
  270. /// </remarks>
  271. /// <seealso cref="MaxElementSize"/>
  272. /// <seealso cref="IsSizeLimited"/>
  273. /// <seealso cref="MaxSize"/>
  274. /// <seealso cref="IsCountLimited"/>
  275. /// <seealso cref="ExpirationTime"/>
  276. long Size { get; }
  277. /// <summary>
  278. /// Gets an object that can be used to synchronize access to the <see cref="ICnmCache{TKey,TValue}"/>.
  279. /// </summary>
  280. /// <value>
  281. /// An object that can be used to synchronize access to the <see cref="ICnmCache{TKey,TValue}"/>.
  282. /// </value>
  283. /// <remarks>
  284. /// <para>
  285. /// To get synchronized (thread safe) access to <see cref="ICnmCache{TKey,TValue}"/>, use <see cref="CnmSynchronizedCache{TKey,TValue}"/>
  286. /// method <see cref="CnmSynchronizedCache{TKey,TValue}.Synchronized"/> to retrieve synchronized wrapper interface to
  287. /// <see cref="ICnmCache{TKey,TValue}"/>.
  288. /// </para>
  289. /// </remarks>
  290. /// <seealso cref="IsSynchronized"/>
  291. /// <seealso cref="CnmSynchronizedCache{TKey,TValue}"/>
  292. object SyncRoot { get; }
  293. /// <summary>
  294. /// Removes all elements from the <see cref="ICnmCache{TKey,TValue}"/>.
  295. /// </summary>
  296. /// <seealso cref="Set"/>
  297. /// <seealso cref="Remove"/>
  298. /// <seealso cref="RemoveRange"/>
  299. /// <seealso cref="TryGetValue"/>
  300. /// <seealso cref="PurgeExpired"/>
  301. void Clear();
  302. /// <summary>
  303. /// Purge expired elements from the <see cref="ICnmCache{TKey,TValue}"/>.
  304. /// </summary>
  305. /// <remarks>
  306. /// <para>
  307. /// Element becomes expired when last access time to it has been longer time than <see cref="ExpirationTime"/>.
  308. /// </para>
  309. /// <para>
  310. /// Depending on <see cref="ICnmCache{TKey,TValue}"/> implementation, some of expired elements
  311. /// may stay longer than <see cref="ExpirationTime"/> in the cache.
  312. /// </para>
  313. /// </remarks>
  314. /// <seealso cref="IsTimeLimited"/>
  315. /// <seealso cref="ExpirationTime"/>
  316. /// <seealso cref="Set"/>
  317. /// <seealso cref="Remove"/>
  318. /// <seealso cref="RemoveRange"/>
  319. /// <seealso cref="TryGetValue"/>
  320. /// <seealso cref="Clear"/>
  321. void PurgeExpired();
  322. /// <summary>
  323. /// Removes element associated with <paramref name="key"/> from the <see cref="ICnmCache{TKey,TValue}"/>.
  324. /// </summary>
  325. /// <param name="key">
  326. /// The key that is associated with element to remove from the <see cref="ICnmCache{TKey,TValue}"/>.
  327. /// </param>
  328. /// <exception cref="ArgumentNullException">
  329. /// <paramref name="key"/> is <see langword="null"/>.
  330. /// </exception>
  331. /// <seealso cref="Set"/>
  332. /// <seealso cref="RemoveRange"/>
  333. /// <seealso cref="TryGetValue"/>
  334. /// <seealso cref="Clear"/>
  335. /// <seealso cref="PurgeExpired"/>
  336. void Remove(TKey key);
  337. /// <summary>
  338. /// Removes elements that are associated with one of <paramref name="keys"/> from the <see cref="ICnmCache{TKey,TValue}"/>.
  339. /// </summary>
  340. /// <param name="keys">
  341. /// The keys that are associated with elements to remove from the <see cref="ICnmCache{TKey,TValue}"/>.
  342. /// </param>
  343. /// <exception cref="ArgumentNullException">
  344. /// <paramref name="keys"/> is <see langword="null"/>.
  345. /// </exception>
  346. /// <seealso cref="Set"/>
  347. /// <seealso cref="Remove"/>
  348. /// <seealso cref="TryGetValue"/>
  349. /// <seealso cref="Clear"/>
  350. /// <seealso cref="PurgeExpired"/>
  351. void RemoveRange(IEnumerable<TKey> keys);
  352. /// <summary>
  353. /// Add or replace an element with the provided <paramref name="key"/>, <paramref name="value"/> and <paramref name="size"/> to
  354. /// <see cref="ICnmCache{TKey,TValue}"/>.
  355. /// </summary>
  356. /// <param name="key">
  357. /// The object used as the key of the element. Can't be <see langword="null"/> reference.
  358. /// </param>
  359. /// <param name="value">
  360. /// The object used as the value of the element to add or replace. <see langword="null"/> is allowed.
  361. /// </param>
  362. /// <param name="size">
  363. /// The element's size. Normally bytes, but can be any suitable unit of measure.
  364. /// </param>
  365. /// <returns>
  366. /// <see langword="true"/> if element has been added successfully to the <see cref="ICnmCache{TKey,TValue}"/>;
  367. /// otherwise <see langword="false"/>.
  368. /// </returns>
  369. /// <exception cref="ArgumentNullException">
  370. /// <paramref name="key"/>is <see langword="null"/>.
  371. /// </exception>
  372. /// <exception cref="ArgumentOutOfRangeException">
  373. /// The element's <paramref name="size"/> is less than 0.
  374. /// </exception>
  375. /// <remarks>
  376. /// <para>
  377. /// If element's <paramref name="size"/> is larger than <see cref="MaxElementSize"/>, then element is
  378. /// not added to the <see cref="ICnmCache{TKey,TValue}"/>, however - possible older element is
  379. /// removed from the <see cref="ICnmCache{TKey,TValue}"/>.
  380. /// </para>
  381. /// <para>
  382. /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
  383. /// <see cref="ICnmCache{TKey,TValue}"/>will remove less recently used elements until it can fit an new element.
  384. /// </para>
  385. /// <para>
  386. /// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
  387. /// <see cref="ICnmCache{TKey,TValue}"/>will remove less recently used elements until it can fit an new element.
  388. /// </para>
  389. /// </remarks>
  390. /// <seealso cref="IsSizeLimited"/>
  391. /// <seealso cref="IsCountLimited"/>
  392. /// <seealso cref="Remove"/>
  393. /// <seealso cref="RemoveRange"/>
  394. /// <seealso cref="TryGetValue"/>
  395. /// <seealso cref="Clear"/>
  396. /// <seealso cref="PurgeExpired"/>
  397. bool Set(TKey key, TValue value, long size);
  398. /// <summary>
  399. /// Gets the <paramref name="value"/> associated with the specified <paramref name="key"/>.
  400. /// </summary>
  401. /// <returns>
  402. /// <see langword="true"/>if the <see cref="ICnmCache{TKey,TValue}"/> contains an element with
  403. /// the specified key; otherwise, <see langword="false"/>.
  404. /// </returns>
  405. /// <param name="key">
  406. /// The key whose <paramref name="value"/> to get.
  407. /// </param>
  408. /// <param name="value">
  409. /// When this method returns, the value associated with the specified <paramref name="key"/>,
  410. /// if the <paramref name="key"/> is found; otherwise, the
  411. /// default value for the type of the <paramref name="value"/> parameter. This parameter is passed uninitialized.
  412. /// </param>
  413. /// <exception cref="ArgumentNullException">
  414. /// <paramref name="key"/>is <see langword="null"/>.
  415. /// </exception>
  416. /// <seealso cref="Set"/>
  417. /// <seealso cref="Remove"/>
  418. /// <seealso cref="RemoveRange"/>
  419. /// <seealso cref="Clear"/>
  420. /// <seealso cref="PurgeExpired"/>
  421. bool TryGetValue(TKey key, out TValue value);
  422. }
  423. }