Skip to content

Commit 4ff65da

Browse files
committed
Alternative implementation
1 parent fd9990e commit 4ff65da

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

JavaScript/5-spare.js

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
'use strict';
2+
3+
class QueueNode {
4+
length = 0;
5+
6+
constructor({ size }) {
7+
this.size = size;
8+
this.buffer = new Array(size);
9+
this.reset();
10+
}
11+
12+
reset() {
13+
this.readIndex = 0;
14+
this.writeIndex = 0;
15+
this.next = null;
16+
}
17+
18+
enqueue(item) {
19+
if (this.writeIndex >= this.size) return false;
20+
this.buffer[this.writeIndex++] = item;
21+
this.length++;
22+
return true;
23+
}
24+
25+
dequeue() {
26+
if (this.length === 0) return null;
27+
const index = this.readIndex++;
28+
const item = this.buffer[index];
29+
this.buffer[index] = null;
30+
this.length--;
31+
return item;
32+
}
33+
}
34+
35+
class UnrolledQueue {
36+
#length = 0;
37+
#nodeSize = 2048;
38+
#head = null;
39+
#tail = null;
40+
#spare = null;
41+
42+
constructor(options = {}) {
43+
const { nodeSize } = options;
44+
if (nodeSize) this.#nodeSize = nodeSize;
45+
const node = this.#createNode();
46+
this.#head = node;
47+
this.#tail = node;
48+
}
49+
50+
#createNode() {
51+
return new QueueNode({ size: this.#nodeSize });
52+
}
53+
54+
get length() {
55+
return this.#length;
56+
}
57+
58+
enqueue(item) {
59+
if (!this.#head.enqueue(item)) {
60+
let node = this.#spare;
61+
if (node) this.#spare = null;
62+
else node = this.#createNode();
63+
this.#head.next = node;
64+
this.#head = node;
65+
this.#head.enqueue(item);
66+
}
67+
this.#length++;
68+
}
69+
70+
dequeue() {
71+
if (this.#length === 0) return null;
72+
const tail = this.#tail;
73+
const item = tail.dequeue();
74+
this.#length--;
75+
if (tail.length > 0) return item;
76+
const next = this.#tail.next;
77+
if (next) {
78+
this.#tail = next;
79+
if (!this.#spare) {
80+
tail.reset();
81+
this.#spare = tail;
82+
}
83+
} else {
84+
tail.reset();
85+
}
86+
return item;
87+
}
88+
}
89+
90+
// Usage
91+
92+
const mq = new UnrolledQueue({ nodeSize: 8 });
93+
94+
for (let id = 0; id < 20; id++) {
95+
mq.enqueue({ id });
96+
}
97+
98+
while (mq.length) {
99+
const task = mq.dequeue();
100+
console.log(`Processing ${task.id}`);
101+
}
102+
103+
for (let id = 100; id < 125; id++) {
104+
mq.enqueue({ id });
105+
}
106+
107+
while (mq.length) {
108+
const task = mq.dequeue();
109+
console.log(`Processing ${task.id}`);
110+
}
111+
112+
for (let id = 100; id < 105; id++) {
113+
mq.enqueue({ id });
114+
}

0 commit comments

Comments
 (0)