|
1 | 1 | 'use strict'; |
2 | 2 |
|
3 | | -const duplicate = (factory, n) => new Array(n).fill().map(() => factory()); |
| 3 | +const duplicate = (factory, n) => new Array(n).fill(null).map(factory); |
4 | 4 |
|
5 | | -const poolify = (factory, min, norm, max) => { |
6 | | - let allocated = norm; |
7 | | - const items = duplicate(factory, norm); |
| 5 | +const poolify = (factory, { size, max, step }) => { |
| 6 | + let allocated = size; |
| 7 | + const instances = duplicate(factory, size); |
8 | 8 | const delayed = []; |
9 | 9 |
|
10 | | - return (par) => { |
11 | | - if (typeof par !== 'function') { |
12 | | - if (items.length < max) { |
13 | | - const request = delayed.shift(); |
14 | | - if (request) { |
15 | | - const c1 = items.length; |
16 | | - console.log(`${c1}->${c1} Recycle item, pass to delayed`); |
17 | | - request(par); |
18 | | - } else { |
19 | | - const c1 = items.length; |
20 | | - items.push(par); |
21 | | - const c2 = items.length; |
22 | | - console.log(`${c1}->${c2} Recycle item, add to pool`); |
23 | | - } |
24 | | - } |
25 | | - return; |
26 | | - } |
27 | | - if (items.length < min && allocated < max) { |
28 | | - const grow = Math.min(max - allocated, norm - items.length); |
| 10 | + const acquire = (callback) => { |
| 11 | + const c1 = instances.length; |
| 12 | + if (instances.length === 0 && allocated < max) { |
| 13 | + const grow = Math.min(max - allocated, size - instances.length); |
29 | 14 | allocated += grow; |
30 | | - const instances = duplicate(factory, grow); |
31 | | - items.push(...instances); |
| 15 | + console.log({ grow }); |
| 16 | + const addition = duplicate(factory, grow); |
| 17 | + instances.push(...addition); |
32 | 18 | } |
33 | | - const c1 = items.length; |
34 | | - const res = items.pop(); |
35 | | - const c2 = items.length; |
36 | | - if (res) { |
37 | | - console.log(`${c1}->${c2} Get from pool, pass to callback`); |
38 | | - par(res); |
| 19 | + const instance = instances.pop(); |
| 20 | + const c2 = instances.length; |
| 21 | + const delta = `Get from pool: ${c1}->${c2} of ${allocated}`; |
| 22 | + if (instance) { |
| 23 | + console.log(`${delta}, pass to callback`); |
| 24 | + callback(instance); |
39 | 25 | } else { |
40 | | - console.log(`${c1}->${c2} Get from pool, add callback to queue`); |
41 | | - delayed.push(par); |
| 26 | + console.log(`${delta}, add callback to queue`); |
| 27 | + delayed.push(callback); |
42 | 28 | } |
43 | 29 | }; |
| 30 | + |
| 31 | + const release = (instance) => { |
| 32 | + const c1 = instances.length; |
| 33 | + if (delayed.length > 0) { |
| 34 | + const request = delayed.shift(); |
| 35 | + const delta = `Recycle item: ${c1}->${c1} of ${allocated}`; |
| 36 | + console.log(`${delta}, pass to delayed`); |
| 37 | + request(instance); |
| 38 | + } else { |
| 39 | + if (instances.length < max) { |
| 40 | + instances.push(instance); |
| 41 | + } |
| 42 | + const c2 = instances.length; |
| 43 | + const delta = `Recycle item: ${c1}->${c2} of ${allocated}`; |
| 44 | + console.log(`${delta}, add to pool`); |
| 45 | + } |
| 46 | + }; |
| 47 | + |
| 48 | + return { acquire, release }; |
44 | 49 | }; |
45 | 50 |
|
46 | 51 | // Usage |
47 | 52 |
|
48 | | -// Factory to allocate 4kb buffer |
49 | 53 | const buffer = () => new Uint32Array(1024); |
50 | 54 |
|
51 | | -// Allocate pool of 10 buffers |
52 | | -const pool = poolify(buffer, 3, 5, 7); |
| 55 | +const pool = poolify(buffer, { size: 5, max: 7, step: 3 }); |
53 | 56 |
|
54 | 57 | let i = 0; |
55 | | - |
56 | 58 | const next = () => { |
57 | | - pool((item) => { |
| 59 | + pool.acquire((data) => { |
58 | 60 | i++; |
59 | 61 | if (i < 20) { |
60 | 62 | setTimeout(next, i * 10); |
61 | | - setTimeout(() => pool(item), i * 100); |
| 63 | + setTimeout(() => pool.release(data), i * 100); |
62 | 64 | } |
63 | 65 | }); |
64 | 66 | }; |
|
0 commit comments