Skip to content

Instantly share code, notes, and snippets.

@kevincennis
Last active March 29, 2016 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevincennis/c83f7b5c1b2a72f61fd5 to your computer and use it in GitHub Desktop.
Save kevincennis/c83f7b5c1b2a72f61fd5 to your computer and use it in GitHub Desktop.
Object Pool

The function or class passed to a Pool instance has to follow the following rules:

  1. It must be safe to call its constructor with no arguments.
  2. It must implement an initObject method.
  3. It must implement a releaseObject method.

When you're done with an object, pass it to Pool#release(), and it will be made available for re-use.

const Pool = (function() {
const cache = new WeakMap();
class Pool {
constructor( target ) {
if ( typeof target !== 'function' ) {
throw TypeError('Pool must be initialized with a target function');
}
if ( !target.prototype.initObject ) {
throw TypeError('Target function does not have an initObject method');
}
if ( !target.prototype.releaseObject ) {
throw TypeError('Target function does not have an releaseObject method');
}
cache.set( this, { pool: [], target });
}
// get a clean instance
create( ...args ) {
let data = cache.get( this );
let obj;
if ( data.pool.length ) {
obj = data.pool.pop();
console.log('re-used an instance');
} else {
obj = new data.target();
console.log('created an instance');
}
obj.initObject( ...args );
return obj;
}
// release an instance
release( obj, ...args ) {
let data = cache.get( this );
if ( !( obj instanceof data.target ) ) {
throw TypeError('Unknown object');
}
obj.releaseObject( ...args );
data.pool.push( obj );
console.log('released an instance');
}
// pre-allocate n instances
allocate( n ) {
let data = cache.get( this );
console.log( `Allocated ${ n } instances` );
while ( n-- ) {
data.pool.push( new data.target() );
}
return n;
}
get size() {
return cache.get( this ).pool.length;
}
}
return Pool;
}());
// stupid example class
class Point {
initObject( x, y ) {
Object.assign( this, { x, y } );
}
releaseObject() {
this.x = this.y = 0;
}
}
// create a new pool
let pool = new Pool( Point );
// pre-allocate some objects
pool.allocate( 2 );
console.log( `Pool size: ${ pool.size }` );
// grab an instance
let point1 = pool.create( 3, 5 ); // use pre-allocated
// grab another instance
let point2 = pool.create( 6, 8 ); // use pre-allocated
// grab another instance
let point3 = pool.create( 6, 8 ); // create new
console.log( `Pool size: ${ pool.size }` );
// release the first one
pool.release( point1 );
console.log( `Pool size: ${ pool.size }` );
// grab an instance
let point4 = pool.create( 10, 12 ); //re-use existing
console.log( `Pool size: ${ pool.size }` );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment