Skip to content

Instantly share code, notes, and snippets.

@YonatanKra
Last active December 16, 2020 14:05
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 YonatanKra/a1a35d11dcfcd74aba25680e740bbd61 to your computer and use it in GitHub Desktop.
Save YonatanKra/a1a35d11dcfcd74aba25680e740bbd61 to your computer and use it in GitHub Desktop.
Object pool with a private pool array
const INCREASE_PERCENT = 50;
const MINIMUM_PERCENT_FREE = 10;
const NULL_ELEMENT = null;
class ObjectPool {
#poolArray = [];
#freeElements = 0;
#freeIndex = 0;
resetFunction = () => {
};
constructorFunction = () => {
};
constructor(constructorFunction, resetFunction = obj => obj, initialSize = 1000) {
this.resetFunction = resetFunction;
this.constructorFunction = constructorFunction;
for (let i = 0; i < initialSize; i++) this.createElement();
}
createElement() {
this.#freeElements++;
this.#poolArray.push(this.resetFunction(this.constructorFunction()));
return this.#poolArray[this.#poolArray.length - 1];
}
increasePoolSize() {
const increaseSize = Math.round(INCREASE_PERCENT * this.#poolArray.length / 100);
for (let i = 0; i < increaseSize; i++) {
this.createElement();
}
this.#freeElements += increaseSize;
}
getElement() {
if (this.#freeElements / this.#poolArray.length <= MINIMUM_PERCENT_FREE / 100) {
this.increasePoolSize();
}
this.#freeElements--;
const freeElement = this.#poolArray[this.#freeIndex];
this.#poolArray[this.#freeIndex++] = NULL_ELEMENT;
return freeElement;
}
releaseElement(element) {
this.#poolArray[--this.#freeIndex] = element;
this.resetFunction(element);
}
get size() {
return this.#poolArray.length;
}
}
const INCREASE_PERCENT = 50;
const MINIMUM_PERCENT_FREE = 10;
class ObjectPoolMember {
previousElement = null;
nextElement = null;
free = true;
constructor(data) {
this.data = data;
}
}
class ObjectPool {
#poolArray = [];
#freeElements = 0;
#nextFree = null;
#lastFree = null;
resetFunction = () => {
};
constructorFunction = () => {
};
constructor(constructorFunction, resetFunction = obj => obj, initialSize = 1000) {
this.resetFunction = resetFunction;
this.constructorFunction = constructorFunction;
for (let i = 0; i < initialSize; i++) this.createElement();
this.#nextFree = this.#poolArray[0];
}
createElement() {
this.#freeElements++;
const data = this.resetFunction(this.constructorFunction());
const newObjectPoolMember = new ObjectPoolMember(data);
this.#poolArray.push(newObjectPoolMember);
if (!this.#lastFree) {
this.#lastFree = newObjectPoolMember;
} else {
this.linkElement(newObjectPoolMember);
}
return newObjectPoolMember;
}
linkElement(element) {
element.previousElement = this.#lastFree;
this.#lastFree.nextElement = element;
this.#lastFree = element;
}
unlinkFirstElement(element) {
this.#nextFree = element.nextElement;
this.#nextFree.previousElement = null;
element.nextElement = this.previousElement = null;
}
catchElement(element) {
element.free = false;
this.#freeElements--;
if (this.#freeElements / this.#poolArray.length < MINIMUM_PERCENT_FREE / 100) {
const increaseSize = Math.round(INCREASE_PERCENT * this.#poolArray.length / 100);
for (let i = 0; i < increaseSize; i++) {
this.createElement();
}
this.#freeElement += increaseSize;
}
}
getElement() {
const availableElement = this.#nextFree;
this.unlinkFirstElement(availableElement);
this.catchElement(availableElement);
return availableElement;
}
setElementAsFree(element) {
element.free = true;
this.linkElement(element);
this.#freeElements++;
}
releaseElement(element) {
this.setElementAsFree(element);
this.resetFunction(element.data);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment