"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=https://github.com/VSCodium/sourcemaps/releases/download/stable-824c4c46a288b839f13b24022655329c2aeb9f81/node_modules-@microsoft-dev-tunnels-ssh-util-queue.js.map