206 lines
5.7 KiB
JavaScript
206 lines
5.7 KiB
JavaScript
// 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}
|
|
*/
|
|
goog.structs.SimplePool = function(initialCount, maxCount) {
|
|
goog.Disposable.call(this);
|
|
|
|
/**
|
|
* Maximum number of objects allowed
|
|
* @type {number}
|
|
* @private
|
|
*/
|
|
this.maxCount_ = maxCount;
|
|
|
|
/**
|
|
* Queue used to store objects that are currently in the pool and available
|
|
* to be used.
|
|
* @type {Array}
|
|
* @private
|
|
*/
|
|
this.freeQueue_ = [];
|
|
|
|
this.createInitial_(initialCount);
|
|
};
|
|
goog.inherits(goog.structs.SimplePool, goog.Disposable);
|
|
|
|
|
|
/**
|
|
* Function for overriding createObject. The avoids a common case requiring
|
|
* subclassing this class.
|
|
* @type {Function}
|
|
* @private
|
|
*/
|
|
goog.structs.SimplePool.prototype.createObjectFn_ = null;
|
|
|
|
|
|
/**
|
|
* Function for overriding disposeObject. The avoids a common case requiring
|
|
* subclassing this class.
|
|
* @type {Function}
|
|
* @private
|
|
*/
|
|
goog.structs.SimplePool.prototype.disposeObjectFn_ = null;
|
|
|
|
|
|
/**
|
|
* 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 createrd 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 {*} 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 {*} 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 overriden by sub-classes to return an instance of the object type
|
|
* that is expected in the pool.
|
|
* @return {*} The created object.
|
|
*/
|
|
goog.structs.SimplePool.prototype.createObject = function() {
|
|
if (this.createObjectFn_) {
|
|
return this.createObjectFn_();
|
|
} else {
|
|
return {};
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Should be overriden 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 {*} 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_;
|
|
};
|