@microsoft/dev-tunnels-ssh
Version:
SSH library for Dev Tunnels
94 lines • 3.08 kB
JavaScript
"use strict";
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
Object.defineProperty(exports, "__esModule", { value: true });
exports.Queue = void 0;
/**
* Generic iterable queue implementation using an auto-expanding circular array buffer.
* Designed to be more efficient for high-volume use compared to a simpler JS queue using
* `Array.shift()` (which would cause a lot of allocations).
*/
class Queue {
constructor() {
this.array = new Array();
this.first = 0;
this.count = 0;
/**
* The version is incremented upon any changes to the queue, so that any iterators can detect the
* change and become invalid. `MAX_SAFE_INTEGER` is 2^53-1 so this isn't likely to ever overflow.
*/
this.version = 0;
}
/**
* Gets the current size of the queue.
*/
get size() {
return this.count;
}
/**
* Adds an item to the end of the queue.
*/
enqueue(item) {
if (this.count === this.array.length) {
const newArray = new Array(Math.max(16, this.count * 2));
for (let i = 0; i < this.count; i++) {
newArray[i] = this.array[(this.first + i) % this.count];
}
this.array = newArray;
this.first = 0;
}
this.array[(this.first + this.count) % this.array.length] = item;
this.count++;
this.version++;
}
/**
* Removes an item from the front of the queue.
* @returns The removed item, or `undefined` if the queue is empty.
*/
dequeue() {
if (this.count === 0)
return undefined;
const item = this.array[this.first];
this.array[this.first] = undefined; // Allow the item to be GC'd.
this.first = (this.first + 1) % this.array.length;
this.count--;
this.version++;
return item;
}
/**
* Gets the item at the front of the queue without removing it.
* @returns The front item, or `undefined` if the queue is empty.
*/
peek() {
if (this.count === 0)
return undefined;
const item = this.array[this.first];
return item;
}
/**
* Clears the queue.
*/
clear() {
this.first = 0;
this.count = 0;
this.array.fill(undefined); // Allow items to be GC'd.
this.version++;
}
/**
* Creates an iterator over the items in the queue.
* (Any changes to the queue will invalidate the iterator.)
*/
*[Symbol.iterator]() {
const iteratorVersion = this.version;
for (let i = 0; i < this.count; i++) {
const item = this.array[(this.first + i) % this.array.length];
yield item;
if (this.version !== iteratorVersion) {
throw new Error('Iterator is invalid due to changes in the collection.');
}
}
}
}
exports.Queue = Queue;
//# sourceMappingURL=queue.js.map