diff --git a/JavaScript/4-bad.js b/JavaScript/4-bad.js index a706074..59dd975 100644 --- a/JavaScript/4-bad.js +++ b/JavaScript/4-bad.js @@ -1,32 +1,79 @@ 'use strict'; -// TODO: Refactor to respect SoC principle and -// optimize JavaScript for V8 - -const poolify = (factory, options, size, max) => { - const instances = []; // Preallocate array - for (let i = 0; i < size; i++) { // Use Array methods instead of loop - const instance = factory(...options); // Avoid array destructuring - instances.push(instance); - } - - return (instance) => { // Respect SoC and SOLID/SRP - if (instance) { // Avoid if-statement - if (instances.length < max) { - instances.push(instance); +const poolify = (factory, size, max) => { + const instances = new Array(size).fill(null).map(factory); + const queue = []; + let available = instances.length; + + const processQueue = () => { + while (queue.length > 0 && available > 0){ + const { resolve } = queue.shift(); + resolve(instances.pop()); + available--; + } + }; + + const acquire = () => { + return new Promise((resolve) => { + if(available > 0){ + const instance = instances.pop(); + available--; + resolve(instance); } + else { + queue.push({ resolve }); + } + }); + }; + + const release = (instance) => { + if (instances.length < max) { + instances.push(instance); + available++; + processQueue(); } - instance = instances.pop(); // Do not reassign incoming parameters - if (!instance) instance = factory(...options); - return instance; }; + + return { acquire, release }; }; // Usage const createBuffer = (size) => new Uint8Array(size); -const pool = poolify(createBuffer, [4096], 10, 15); -const instance = pool(); -console.log({ instance }); -pool(instance); +const bufferSize = 4096; +const createFileBuffer = () => createBuffer(bufferSize); + +const size = 2; +const max = 4; +const pool = poolify(createFileBuffer, size, max); + +(async () => { + const instance1 = await pool.acquire(); + console.log('Acquired instance 1', instance1); + setTimeout(() => { + console.log('Releasing instance 1'); + pool.release(instance1); + }, 1000); + + const instance2 = await pool.acquire(); + console.log('Acquired instance 2', instance2); + setTimeout(() => { + console.log('Releasing instance 2'); + pool.release(instance2); + }, 1500); + + const instance3 = await pool.acquire(); + console.log('Acquired instance 3', instance3); + setTimeout(() => { + console.log('Releasing instance 3'); + pool.release(instance3); + }, 1000); + + const instance4 = await pool.acquire(); + console.log('Acquired instance 4', instance4); + setTimeout(() => { + console.log('Releasing instance 4'); + pool.release(instance4); + }, 1500); +})(); \ No newline at end of file diff --git a/JavaScript/4-improved.js b/JavaScript/4-improved.js index 20a016e..0271975 100644 --- a/JavaScript/4-improved.js +++ b/JavaScript/4-improved.js @@ -1,17 +1,42 @@ 'use strict'; -const poolify = (factory, { size, max }) => { - const instances = new Array(size).fill(null).map(factory); - - const acquire = () => instances.pop() || factory(); +class ObjectPool { + constructor (factory, { size, max }) { + this.factory = factory; + this.max = max; + this.instances = new Array(size).fill(null).map(() => this.factory()); + this.queue = []; + this.available = this.instances.length; + }; - const release = (instance) => { - if (instances.length < max) { - instances.push(instance); + _processQueue() { + while (this.queue.length > 0 && this.available > 0){ + const { resolve } = this.queue.shift(); + resolve(this.instances.pop()); + this.available--; } }; - return { acquire, release }; + acquire () { + return new Promise((resolve) => { + if(this.available > 0){ + const instance = this.instances.pop(); + this.available--; + resolve(instance); + } + else{ + this.queue.push({ resolve }); + } + }); + }; + + release (instance) { + if (this.instances.length < this.max) { + this.instances.push(instance); + this.available++; + this._processQueue(); + } + }; }; // Usage @@ -21,7 +46,34 @@ const createBuffer = (size) => new Uint8Array(size); const FILE_BUFFER_SIZE = 4096; const createFileBuffer = () => createBuffer(FILE_BUFFER_SIZE); -const pool = poolify(createFileBuffer, { size: 10, max: 15 }); -const instance = pool.acquire(); -console.log({ instance }); -pool.release(instance); +const pool = new ObjectPool(createFileBuffer, { size: 2, max: 4 }); + +(async () => { + const instance1 = await pool.acquire(); + console.log('Acquired instance 1', instance1); + setTimeout(() => { + console.log('Releasing instance 1'); + pool.release(instance1); + }, 1000); + + const instance2 = await pool.acquire(); + console.log('Acquired instance 2', instance2); + setTimeout(() => { + console.log('Releasing instance 2'); + pool.release(instance2); + }, 1500); + + const instance3 = await pool.acquire(); + console.log('Acquired instance 3', instance3); + setTimeout(() => { + console.log('Releasing instance 3'); + pool.release(instance3); + }, 1000); + + const instance4 = await pool.acquire(); + console.log('Acquired instance 4', instance4); + setTimeout(() => { + console.log('Releasing instance 4'); + pool.release(instance4); + }, 1500); +})(); \ No newline at end of file pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy