LruCache.html 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-util-LruCache'>/**
  19. </span> * @private
  20. * @class Ext.util.LruCache
  21. * @extend Ext.util.HashMap
  22. * A linked {@link Ext.util.HashMap HashMap} implementation which maintains most recently accessed
  23. * items at the end of the list, and purges the cache down to the most recently accessed {@link #maxSize} items
  24. * upon add.
  25. */
  26. Ext.define('Ext.util.LruCache', {
  27. extend: 'Ext.util.HashMap',
  28. <span id='Ext-util-LruCache-cfg-maxSize'> /**
  29. </span> * @cfg {Number} maxSize The maximum size the cache is allowed to grow to before further additions cause
  30. * removal of the least recently used entry.
  31. */
  32. constructor: function(config) {
  33. Ext.apply(this, config);
  34. this.callParent([config]);
  35. },
  36. /*
  37. * @inheritdoc
  38. */
  39. add: function(key, newValue) {
  40. var me = this,
  41. existingKey = me.findKey(newValue),
  42. entry;
  43. // &quot;new&quot; value is in the list.
  44. if (existingKey) {
  45. me.unlinkEntry(entry = me.map[existingKey]);
  46. entry.prev = me.last;
  47. entry.next = null;
  48. }
  49. // Genuinely new: create an entry for it.
  50. else {
  51. entry = {
  52. prev: me.last,
  53. next: null,
  54. key: key,
  55. value: newValue
  56. };
  57. }
  58. // If the list is not empty, update the last entry
  59. if (me.last) {
  60. me.last.next = entry;
  61. }
  62. // List is empty
  63. else {
  64. me.first = entry;
  65. }
  66. me.last = entry;
  67. me.callParent([key, entry]);
  68. me.prune();
  69. return newValue;
  70. },
  71. // @private
  72. insertBefore: function(key, newValue, sibling) {
  73. var me = this,
  74. existingKey,
  75. entry;
  76. // NOT an assignment.
  77. // If there is a following sibling
  78. if (sibling = this.map[this.findKey(sibling)]) {
  79. existingKey = me.findKey(newValue);
  80. // &quot;new&quot; value is in the list.
  81. if (existingKey) {
  82. me.unlinkEntry(entry = me.map[existingKey]);
  83. }
  84. // Genuinely new: create an entry for it.
  85. else {
  86. entry = {
  87. prev: sibling.prev,
  88. next: sibling,
  89. key: key,
  90. value: newValue
  91. };
  92. }
  93. if (sibling.prev) {
  94. entry.prev.next = entry;
  95. } else {
  96. me.first = entry;
  97. }
  98. entry.next = sibling;
  99. sibling.prev = entry;
  100. me.prune();
  101. return newValue;
  102. }
  103. // No following sibling, it's just an add.
  104. else {
  105. return me.add(key, newValue);
  106. }
  107. },
  108. /*
  109. * @inheritdoc
  110. */
  111. get: function(key) {
  112. var entry = this.map[key];
  113. if (entry) {
  114. // If it's not the end, move to end of list on get
  115. if (entry.next) {
  116. this.moveToEnd(entry);
  117. }
  118. return entry.value;
  119. }
  120. },
  121. /*
  122. * @private
  123. */
  124. removeAtKey: function(key) {
  125. this.unlinkEntry(this.map[key]);
  126. return this.callParent(arguments);
  127. },
  128. /*
  129. * @inheritdoc
  130. */
  131. clear: function(/* private */ initial) {
  132. this.first = this.last = null;
  133. return this.callParent(arguments);
  134. },
  135. // private. Only used by internal methods.
  136. unlinkEntry: function(entry) {
  137. // Stitch the list back up.
  138. if (entry) {
  139. if (entry.next) {
  140. entry.next.prev = entry.prev;
  141. } else {
  142. this.last = entry.prev;
  143. }
  144. if (entry.prev) {
  145. entry.prev.next = entry.next;
  146. } else {
  147. this.first = entry.next;
  148. }
  149. entry.prev = entry.next = null;
  150. }
  151. },
  152. // private. Only used by internal methods.
  153. moveToEnd: function(entry) {
  154. this.unlinkEntry(entry);
  155. // NOT an assignment.
  156. // If the list is not empty, update the last entry
  157. if (entry.prev = this.last) {
  158. this.last.next = entry;
  159. }
  160. // List is empty
  161. else {
  162. this.first = entry;
  163. }
  164. this.last = entry;
  165. },
  166. /*
  167. * @private
  168. */
  169. getArray: function(isKey) {
  170. var arr = [],
  171. entry = this.first;
  172. while (entry) {
  173. arr.push(isKey ? entry.key: entry.value);
  174. entry = entry.next;
  175. }
  176. return arr;
  177. },
  178. <span id='Ext-util-LruCache-method-each'> /**
  179. </span> * Executes the specified function once for each item in the cache.
  180. * Returning false from the function will cease iteration.
  181. *
  182. * By default, iteration is from least recently used to most recent.
  183. *
  184. * The paramaters passed to the function are:
  185. * &lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
  186. * &lt;li&gt;&lt;b&gt;key&lt;/b&gt; : String&lt;p class=&quot;sub-desc&quot;&gt;The key of the item&lt;/p&gt;&lt;/li&gt;
  187. * &lt;li&gt;&lt;b&gt;value&lt;/b&gt; : Number&lt;p class=&quot;sub-desc&quot;&gt;The value of the item&lt;/p&gt;&lt;/li&gt;
  188. * &lt;li&gt;&lt;b&gt;length&lt;/b&gt; : Number&lt;p class=&quot;sub-desc&quot;&gt;The total number of items in the hash&lt;/p&gt;&lt;/li&gt;
  189. * &lt;/ul&gt;&lt;/div&gt;
  190. * @param {Function} fn The function to execute.
  191. * @param {Object} scope The scope (&lt;code&gt;this&lt;/code&gt; reference) to execute in. Defaults to this LruCache.
  192. * @param {Boolean} [reverse=false] Pass &lt;code&gt;true&lt;/code&gt; to iterate the list in reverse (most recent first) order.
  193. * @return {Ext.util.LruCache} this
  194. */
  195. each: function(fn, scope, reverse) {
  196. var me = this,
  197. entry = reverse ? me.last : me.first,
  198. length = me.length;
  199. scope = scope || me;
  200. while (entry) {
  201. if (fn.call(scope, entry.key, entry.value, length) === false) {
  202. break;
  203. }
  204. entry = reverse ? entry.prev : entry.next;
  205. }
  206. return me;
  207. },
  208. <span id='Ext-util-LruCache-method-findKey'> /**
  209. </span> * @private
  210. */
  211. findKey: function(value) {
  212. var key,
  213. map = this.map;
  214. for (key in map) {
  215. if (map.hasOwnProperty(key) &amp;&amp; map[key].value === value) {
  216. return key;
  217. }
  218. }
  219. return undefined;
  220. },
  221. <span id='Ext-util-LruCache-method-prune'> /**
  222. </span> * Purge the least recently used entries if the maxSize has been exceeded.
  223. */
  224. prune: function() {
  225. var me = this,
  226. purgeCount = me.maxSize ? (me.length - me.maxSize) : 0;
  227. if (purgeCount &gt; 0) {
  228. for (; me.first &amp;&amp; purgeCount; purgeCount--) {
  229. me.removeAtKey(me.first.key);
  230. }
  231. }
  232. }
  233. <span id='Ext-util-LruCache-method-containsKey'> /**
  234. </span> * @method containsKey
  235. * @private
  236. */
  237. <span id='Ext-util-LruCache-method-contains'> /**
  238. </span> * @method contains
  239. * @private
  240. */
  241. <span id='Ext-util-LruCache-method-getKeys'> /**
  242. </span> * @method getKeys
  243. * @private
  244. */
  245. <span id='Ext-util-LruCache-method-getValues'> /**
  246. </span> * @method getValues
  247. * @private
  248. */
  249. });</pre>
  250. </body>
  251. </html>