-
Notifications
You must be signed in to change notification settings - Fork 21
/
pool.ts
79 lines (73 loc) · 1.73 KB
/
pool.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { BitArray } from "./bit-array.ts";
import { getLSBIndex } from "./utilities.ts";
/**
* Implements a fast algorithm to manage availability of objects in an object pool using a BitArray.
*
* @example
* // create a pool of 1600 indexes
* const pool = Pool.create(100 * 16);
*
* // get the next available index and make it unavailable
* pool.get();
* //=> 0
* pool.get();
* //=> 1
*
* // set index available
* pool.free(0);
* pool.get();
* //=> 0
*
* pool.get();
* //=> 2
*/
export class Pool extends BitArray {
nextAvailable = 0;
/**
* Creates a Pool of the specified size.
*
* @param size the size of the pool
* @return a new Pool
*/
static create<T extends typeof BitArray>(
this: T,
size: number,
): InstanceType<T> {
const pool = new this(this.getLength(size));
pool.fill(4294967295);
return pool as InstanceType<T>;
}
/**
* Makes a given index available.
*
* @param index index to be freed
*/
free(index: number): void {
const { bucket, position } = this.getBitPosition(index);
this[bucket] |= 1 << position;
this.nextAvailable = bucket;
}
/**
* Gets the next available index in the pool.
*
* @return the next available index
*/
get(): number {
const { nextAvailable } = this;
if (!~nextAvailable) return -1;
const record = this[nextAvailable];
const index = getLSBIndex(record);
this[nextAvailable] &= ~(1 << index);
// record is full, find next empty
if (this[nextAvailable] === 0) {
this.nextAvailable = -1;
for (let i = 0; i < this.length; i++) {
if (this[i] !== 0) {
this.nextAvailable = i;
break;
}
}
}
return (nextAvailable << 5) + index;
}
}