-
Notifications
You must be signed in to change notification settings - Fork 8
/
fifo.js
99 lines (84 loc) · 2.75 KB
/
fifo.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
93
94
95
96
97
98
99
/* used for event generation */
var Events = require('events');
/* async fifo class */
class Fifo extends Events.EventEmitter
{
/* constructor */
constructor(size)
{
/* call event emitter class constructor */
super();
/* initalize values */
this._q = [];
this._size = size;
/* bindings */
this.enqueue = this.enqueue.bind(this);
this.dequeue = this.dequeue.bind(this);
this.tryDequeue = this.tryDequeue.bind(this);
}
/* enqueue element */
enqueue(element, callback)
{
/* wait for dequeue event to be emited */
var dequeued = () => {
/* no space in queue? */
if (this._size && this._q.length == this._size)
return;
/* store value */
this._q.push(element);
/* listener is no longer needed */
this.removeListener('dequeue', dequeued);
/* notify others on the next event loop iteration */
process.nextTick(() => this.emit('enqueue'));
/* execute callback */
callback(null);
};
/* subscripe to dequeue event */
this.on('dequeue', dequeued);
/* force execution to check if we have free space in queue */
dequeued();
}
/* dequeue element */
dequeue(callback)
{
/* wait for enqueue event to be emited */
var enqueued = () => {
/* no elements in queue? */
if (this._q.length == 0)
return;
/* get element from queue */
var element = this._q.shift();
/* remove listener */
this.removeListener('enqueue', enqueued);
/* notify others on the next event loop iteration */
process.nextTick(() => this.emit('dequeue'));
/* return value from fifo */
callback(null, element);
};
/* subscripe to enqueue event */
this.on('enqueue', enqueued);
/* force execution to check if we have elements in queue */
enqueued();
}
/* synchronous dequeue operation: returns element or null if there
* is nothing on the queue */
tryDequeue()
{
/* no element on queue */
if (this._q.length == 0)
return null;
/* notify others on the next event loop iteration */
process.nextTick(() => this.emit('dequeue'));
/* return element value */
return this._q.shift();
}
/* flush all data */
flush()
{
this._q.length = 0;
/* emit dequeue event */
this.emit('dequeue');
}
}
/* export class */
module.exports = Fifo;