-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcircular-buffer.js
92 lines (70 loc) · 1.9 KB
/
circular-buffer.js
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
80
81
82
83
84
85
86
87
88
89
90
91
92
export const BufferEmptyError = new Error("Buffer is empty");
export const BufferFullError = new Error("Buffer is full");
class CircularIndexer {
constructor(targetBuffer) {
this._targetBuffer = targetBuffer;
this._index = 0;
}
get index() {
return this._index;
}
set index(rawIndex) {
this._index = this.formatLocalIndex(rawIndex);
}
getValue() {
return this._targetBuffer[this.index];
}
setValue(newValue) {
this._targetBuffer[this.index] = newValue;
}
increment(amount = 1) {
this.index = this.index + amount;
}
formatLocalIndex(rawIndex) {
return CircularIndexer.formatIndex(rawIndex, this._targetBuffer.length);
}
static formatIndex(rawIndex, bufferSize) {
return rawIndex % bufferSize;
}
}
export default class circularBuffer {
constructor(size) {
this.reset(size);
}
read() {
if (this.isEmpty()) throw BufferEmptyError;
const currentValue = this._readIndexer.getValue();
this._readIndexer.setValue(undefined);
this._readIndexer.increment();
return currentValue;
}
write(value) {
this.doWrite(value, () => {
throw BufferFullError;
});
}
forceWrite(value) {
this.doWrite(value, () => {
this._readIndexer.index = this._writeIndexer.index + 1;
});
}
doWrite(value, onBufferFull) {
if (value === null || value === undefined) return;
if (this._writeIndexer.getValue() !== undefined) {
onBufferFull();
}
this._writeIndexer.setValue(value);
this._writeIndexer.increment();
}
isEmpty() {
return this._internalRepresentation.every(item => item === undefined);
}
clear() {
this.reset(this._internalRepresentation.length);
}
reset(size) {
this._internalRepresentation = new Array(size);
this._readIndexer = new CircularIndexer(this._internalRepresentation);
this._writeIndexer = new CircularIndexer(this._internalRepresentation);
}
}