123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- // Copyright 2007 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview Datastructure: Pool.
- *
- *
- * A generic class for handling pools of objects that is more efficient than
- * goog.structs.Pool because it doesn't maintain a list of objects that are in
- * use. See constructor comment.
- */
- goog.provide('goog.structs.SimplePool');
- goog.require('goog.Disposable');
- /**
- * A generic pool class. Simpler and more efficient than goog.structs.Pool
- * because it doesn't maintain a list of objects that are in use. This class
- * has constant overhead and doesn't create any additional objects as part of
- * the pool management after construction time.
- *
- * IMPORTANT: If the objects being pooled are arrays or maps that can have
- * unlimited number of properties, they need to be cleaned before being
- * returned to the pool.
- *
- * Also note that {@see goog.object.clean} actually allocates an array to clean
- * the object passed to it, so simply using this function would defy the
- * purpose of using the pool.
- *
- * @param {number} initialCount Initial number of objects to populate the free
- * pool at construction time.
- * @param {number} maxCount Maximum number of objects to keep in the free pool.
- * @constructor
- * @extends {goog.Disposable}
- * @template T
- */
- goog.structs.SimplePool = function(initialCount, maxCount) {
- goog.Disposable.call(this);
- /**
- * Function for overriding createObject. The avoids a common case requiring
- * subclassing this class.
- * @private {Function}
- */
- this.createObjectFn_ = null;
- /**
- * Function for overriding disposeObject. The avoids a common case requiring
- * subclassing this class.
- * @private {Function}
- */
- this.disposeObjectFn_ = null;
- /**
- * Maximum number of objects allowed
- * @private {number}
- */
- this.maxCount_ = maxCount;
- /**
- * Queue used to store objects that are currently in the pool and available
- * to be used.
- * @private {Array<T>}
- */
- this.freeQueue_ = [];
- this.createInitial_(initialCount);
- };
- goog.inherits(goog.structs.SimplePool, goog.Disposable);
- /**
- * Sets the {@code createObject} function which is used for creating a new
- * object in the pool.
- * @param {Function} createObjectFn Create object function which returns the
- * newly created object.
- */
- goog.structs.SimplePool.prototype.setCreateObjectFn = function(createObjectFn) {
- this.createObjectFn_ = createObjectFn;
- };
- /**
- * Sets the {@code disposeObject} function which is used for disposing of an
- * object in the pool.
- * @param {Function} disposeObjectFn Dispose object function which takes the
- * object to dispose as a parameter.
- */
- goog.structs.SimplePool.prototype.setDisposeObjectFn = function(
- disposeObjectFn) {
- this.disposeObjectFn_ = disposeObjectFn;
- };
- /**
- * Gets an unused object from the the pool, if there is one available,
- * otherwise creates a new one.
- * @return {T} An object from the pool or a new one if necessary.
- */
- goog.structs.SimplePool.prototype.getObject = function() {
- if (this.freeQueue_.length) {
- return this.freeQueue_.pop();
- }
- return this.createObject();
- };
- /**
- * Returns an object to the pool so that it can be reused. If the pool is
- * already full, the object is disposed instead.
- * @param {T} obj The object to release.
- */
- goog.structs.SimplePool.prototype.releaseObject = function(obj) {
- if (this.freeQueue_.length < this.maxCount_) {
- this.freeQueue_.push(obj);
- } else {
- this.disposeObject(obj);
- }
- };
- /**
- * Populates the pool with initialCount objects.
- * @param {number} initialCount The number of objects to add to the pool.
- * @private
- */
- goog.structs.SimplePool.prototype.createInitial_ = function(initialCount) {
- if (initialCount > this.maxCount_) {
- throw Error('[goog.structs.SimplePool] Initial cannot be greater than max');
- }
- for (var i = 0; i < initialCount; i++) {
- this.freeQueue_.push(this.createObject());
- }
- };
- /**
- * Should be overridden by sub-classes to return an instance of the object type
- * that is expected in the pool.
- * @return {T} The created object.
- */
- goog.structs.SimplePool.prototype.createObject = function() {
- if (this.createObjectFn_) {
- return this.createObjectFn_();
- } else {
- return {};
- }
- };
- /**
- * Should be overrideen to dispose of an object. Default implementation is to
- * remove all of the object's members, which should render it useless. Calls the
- * object's dispose method, if available.
- * @param {T} obj The object to dispose.
- */
- goog.structs.SimplePool.prototype.disposeObject = function(obj) {
- if (this.disposeObjectFn_) {
- this.disposeObjectFn_(obj);
- } else if (goog.isObject(obj)) {
- if (goog.isFunction(obj.dispose)) {
- obj.dispose();
- } else {
- for (var i in obj) {
- delete obj[i];
- }
- }
- }
- };
- /**
- * Disposes of the pool and all objects currently held in the pool.
- * @override
- * @protected
- */
- goog.structs.SimplePool.prototype.disposeInternal = function() {
- goog.structs.SimplePool.superClass_.disposeInternal.call(this);
- // Call disposeObject on each object held by the pool.
- var freeQueue = this.freeQueue_;
- while (freeQueue.length) {
- this.disposeObject(freeQueue.pop());
- }
- delete this.freeQueue_;
- };
|