| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>  <style type="text/css">    .highlight { display: block; background-color: #ddd; }  </style>  <script type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-util-LruCache'>/**</span> * @private * @class Ext.util.LruCache * @extend Ext.util.HashMap * A linked {@link Ext.util.HashMap HashMap} implementation which maintains most recently accessed * items at the end of the list, and purges the cache down to the most recently accessed {@link #maxSize} items * upon add. */Ext.define('Ext.util.LruCache', {    extend: 'Ext.util.HashMap',<span id='Ext-util-LruCache-cfg-maxSize'>    /**</span>     * @cfg {Number} maxSize The maximum size the cache is allowed to grow to before further additions cause     * removal of the least recently used entry.     */    constructor: function(config) {        Ext.apply(this, config);        this.callParent([config]);    },    /*     * @inheritdoc     */    add: function(key, newValue) {        var me = this,            existingKey = me.findKey(newValue),            entry;        // "new" value is in the list.        if (existingKey) {            me.unlinkEntry(entry = me.map[existingKey]);            entry.prev = me.last;            entry.next = null;        }        // Genuinely new: create an entry for it.        else {            entry = {                prev: me.last,                next: null,                key: key,                value: newValue            };        }        // If the list is not empty, update the last entry        if (me.last) {            me.last.next = entry;        }        // List is empty        else {            me.first = entry;        }        me.last = entry;        me.callParent([key, entry]);        me.prune();        return newValue;    },    // @private    insertBefore: function(key, newValue, sibling) {        var me = this,            existingKey,            entry;        // NOT an assignment.        // If there is a following sibling        if (sibling = this.map[this.findKey(sibling)]) {            existingKey = me.findKey(newValue);            // "new" value is in the list.            if (existingKey) {                me.unlinkEntry(entry = me.map[existingKey]);            }            // Genuinely new: create an entry for it.            else {                entry = {                    prev: sibling.prev,                    next: sibling,                    key: key,                    value: newValue                };            }            if (sibling.prev) {                entry.prev.next = entry;            } else {                me.first = entry;            }            entry.next = sibling;            sibling.prev = entry;            me.prune();            return newValue;        }        // No following sibling, it's just an add.        else {            return me.add(key, newValue);        }    },    /*     * @inheritdoc     */    get: function(key) {        var entry = this.map[key];        if (entry) {            // If it's not the end, move to end of list on get            if (entry.next) {                this.moveToEnd(entry);            }            return entry.value;        }    },    /*     * @private     */    removeAtKey: function(key) {        this.unlinkEntry(this.map[key]);        return this.callParent(arguments);    },    /*     * @inheritdoc     */    clear: function(/* private */ initial) {        this.first = this.last = null;        return this.callParent(arguments);    },    // private. Only used by internal methods.    unlinkEntry: function(entry) {        // Stitch the list back up.        if (entry) {            if (entry.next) {                entry.next.prev = entry.prev;            } else {                this.last = entry.prev;            }            if (entry.prev) {                entry.prev.next = entry.next;            } else {                this.first = entry.next;            }            entry.prev = entry.next = null;        }    },    // private. Only used by internal methods.    moveToEnd: function(entry) {        this.unlinkEntry(entry);        // NOT an assignment.        // If the list is not empty, update the last entry        if (entry.prev = this.last) {            this.last.next = entry;        }        // List is empty        else {            this.first = entry;        }        this.last = entry;    },    /*     * @private     */    getArray: function(isKey) {        var arr = [],            entry = this.first;        while (entry) {            arr.push(isKey ? entry.key: entry.value);            entry = entry.next;        }        return arr;    },<span id='Ext-util-LruCache-method-each'>    /**</span>     * Executes the specified function once for each item in the cache.     * Returning false from the function will cease iteration.     *     * By default, iteration is from least recently used to most recent.     *     * The paramaters passed to the function are:     * <div class="mdetail-params"><ul>     * <li><b>key</b> : String<p class="sub-desc">The key of the item</p></li>     * <li><b>value</b> : Number<p class="sub-desc">The value of the item</p></li>     * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the hash</p></li>     * </ul></div>     * @param {Function} fn The function to execute.     * @param {Object} scope The scope (<code>this</code> reference) to execute in. Defaults to this LruCache.     * @param {Boolean} [reverse=false] Pass <code>true</code> to iterate the list in reverse (most recent first) order.     * @return {Ext.util.LruCache} this     */    each: function(fn, scope, reverse) {        var me = this,            entry = reverse ? me.last : me.first,            length = me.length;        scope = scope || me;        while (entry) {            if (fn.call(scope, entry.key, entry.value, length) === false) {                break;            }            entry = reverse ? entry.prev : entry.next;        }        return me;    },<span id='Ext-util-LruCache-method-findKey'>    /**</span>     * @private     */    findKey: function(value) {        var key,            map = this.map;        for (key in map) {            if (map.hasOwnProperty(key) && map[key].value === value) {                return key;            }        }        return undefined;    },<span id='Ext-util-LruCache-method-prune'>    /**</span>     * Purge the least recently used entries if the maxSize has been exceeded.     */    prune: function() {        var me = this,            purgeCount = me.maxSize ? (me.length - me.maxSize) : 0;        if (purgeCount > 0) {            for (; me.first && purgeCount; purgeCount--) {                me.removeAtKey(me.first.key);            }        }    }<span id='Ext-util-LruCache-method-containsKey'>  /**</span>   * @method containsKey   * @private   */<span id='Ext-util-LruCache-method-contains'>  /**</span>   * @method contains   * @private   */<span id='Ext-util-LruCache-method-getKeys'>  /**</span>   * @method getKeys   * @private   */<span id='Ext-util-LruCache-method-getValues'>  /**</span>   * @method getValues   * @private   */});</pre></body></html>
 |