yqueue
Version:
Yet another concurrent task queue
57 lines • 1.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.YSemaphore = void 0;
const binary_heap_1 = require("./binary-heap");
class YSemaphore {
constructor(permits) {
this.permits = permits;
this.sequence = 0;
if (!(permits > 0) || Math.floor(permits) !== permits) {
throw new Error(`permits must be a positive integer`);
}
this.slots = Array.from({ length: permits }).fill(false);
this.availableSlots = this.slots.map((_, i) => i);
this.pq = new binary_heap_1.BinaryHeap((a, b) => {
if (a.priority !== b.priority)
return a.priority - b.priority;
return b.sequence - a.sequence;
});
}
getAvailablePermits() {
return this.availableSlots.length;
}
getQueueLength() {
return this.pq.length;
}
async acquire(priority) {
const slot = this.availableSlots.pop();
if (slot !== undefined) {
this.slots[slot] = true;
return slot;
}
return new Promise(f => {
this.pq.add({
priority: priority !== null && priority !== void 0 ? priority : 0,
sequence: this.sequence++,
ack: f,
});
});
}
release(acquired) {
if (acquired < 0 ||
acquired >= this.slots.length ||
!this.slots[acquired]) {
return;
}
const next = this.pq.removeMax();
if (next === null) {
this.slots[acquired] = false;
this.availableSlots.push(acquired);
}
else {
next.ack(acquired);
}
}
}
exports.YSemaphore = YSemaphore;
//# sourceMappingURL=y-semaphore.js.map