UNPKG

yqueue

Version:

Yet another concurrent task queue

57 lines 1.77 kB
"use strict"; 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