/** * This class provides an **unordered** collection similar to `Ext.util.Collection`. The * removal of order maintenance provides a significant performance increase. Further, this * class does not provide events or other high-level features. It maintains an array of * `items` and a map to quickly find items by their `id`. * * @private * @since 5.1.1 */Ext.define('Ext.util.Bag', { isBag: true, constructor: function () { /** * @property {Object[]} items * An array containing the items. * @private * @since 5.1.1 */ this.items = []; /** * @property {Object} map * An object used as a map to find items based on their key. * @private * @since 5.1.1 */ this.map = {}; }, /** * @property {Number} generation * Mutation counter which is incremented when the collection changes. * @readonly * @since 5.1.1 */ generation: 0, /** * @property {Number} length * The count of items in the collection. * @readonly * @since 5.1.1 */ length: 0, add: function (item) { var me = this, id = me.getKey(item), map = me.map, items = me.items, idx = map[id], old; if (idx === undefined) { items.push(item); map[id] = me.length++; old = item; } else { old = items[idx]; items[idx] = item; } ++me.generation; return old; }, clear: function () { var me = this, needsClear = me.generation || me.length, ret = needsClear ? me.items : []; if (needsClear) { me.items = []; me.length = 0; me.map = {}; ++me.generation; } return ret; }, clone: function () { var me = this, ret = new me.self(), len = me.length; if (len) { Ext.apply(ret.map, me.map); ret.items = me.items.slice(); ret.length = me.length; } return ret; }, contains: function(item) { var ret = false, map = this.map, key; if (item != null) { key = this.getKey(item); if (key in map) { ret = this.items[map[key]] === item; } } return ret; }, containsKey: function(key) { return key in this.map; }, destroy: function () { this.items = this.map = null; this.callParent(); }, getAt: function(index) { var out = null; if (index < this.length) { out = this.items[index]; } return out; }, getByKey: function(key) { var map = this.map, ret = null; if (key in map) { ret = this.items[map[key]]; } return ret; }, getCount: function() { return this.length; }, getKey: function (item) { return item.id || item.getId(); }, remove: function (item) { var me = this, map = me.map, items = me.items, old = null, idx, id, last; if (me.length) { idx = map[id = me.getKey(item)]; if (idx !== undefined) { delete map[id]; old = items[idx]; last = items.pop(); if (idx < --me.length) { items[idx] = last; map[me.getKey(last)] = idx; } ++me.generation; } } return old; }, removeByKey: function(key) { var item = this.getByKey(key); if (item) { this.remove(item); } return item || null; }, sort: function (fn) { var me = this, items = me.items, n = items.length, item; if (n) { Ext.Array.sort(items, fn); me.map = {}; while (n-- > 0) { item = items[n]; me.map[me.getKey(item)] = n; } ++me.generation; } }});