UNPKG

@itwin/core-bentley

Version:

Bentley JavaScript core components

97 lines 4.42 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Collections */ Object.defineProperty(exports, "__esModule", { value: true }); exports.IndexMap = exports.IndexedValue = void 0; const SortedArray_1 = require("./SortedArray"); /** Associates a value of type T with an index representing its insertion order in an IndexMap<T> * @public */ class IndexedValue { value; index; constructor(value, index) { this.value = value; this.index = index; } } exports.IndexedValue = IndexedValue; /** * Maintains a set of unique elements in sorted order and retains the insertion order of each. * The uniqueness of the elements is determined by a comparison routine supplied by the user. * The user may also supply a maximum size, beyond which insertions will fail. * @public */ class IndexMap { _array = []; _compareValues; _clone; _maximumSize; /** * Construct a new IndexMap<T>. * @param compare The function used to compare elements within the map. * @param maximumSize The maximum number of elements permitted in the IndexMap. The maximum index of an element is maximumSize-1. * @param clone The function invoked to clone a new element for insertion into the array. The default implementation simply returns its input. */ constructor(compare, maximumSize = Number.MAX_SAFE_INTEGER, clone = SortedArray_1.shallowClone) { this._compareValues = compare; this._clone = clone; this._maximumSize = maximumSize; } /** The number of elements in the map. */ get length() { return this._array.length; } /** Returns true if the maximum number of elements have been inserted. */ get isFull() { return this.length >= this._maximumSize; } /** Returns true if the map contains no elements. */ get isEmpty() { return 0 === this.length; } /** Removes all elements from the map. */ clear() { this._array = []; } /** Attempt to insert a new value into the map. * If an equivalent element already exists in the map, the corresponding index is returned. * If the map is full, nothing is inserted and -1 is returned. * Otherwise: * The new element is mapped to the next-available index (that is, the length of the map prior to insertion of this new element); * the value is cloned using the function supplied to the IndexMap constructor; * the cloned result is inserted into the map; and * the index of the new element is returned. * @param value The value to insert * @param onInsert The optional callback method to call if insertion occurs with the inserted value * @returns the index of the equivalent element in the map, or -1 if the map is full and no equivalent element exists. */ insert(value, onInsert) { const bound = this.lowerBound(value); if (bound.equal) return this._array[bound.index].index; else if (this.isFull) return -1; const entry = new IndexedValue(this._clone(value), this._array.length); if (undefined !== onInsert) onInsert(entry.value); this._array.splice(bound.index, 0, entry); return entry.index; } /** * Finds the index of an element equivalent to the supplied value. * @param value the value to find * @returns the index of an equivalent element in the map, or -1 if no such element exists. */ indexOf(value) { const bound = this.lowerBound(value); return bound.equal ? this._array[bound.index].index : -1; } lowerBound(value) { return (0, SortedArray_1.lowerBound)(value, this._array, (lhs, rhs) => this._compareValues(lhs, rhs.value)); } /** Return an array of the elements in this map in which the array index of each element corresponds to the index assigned to it by the map. */ toArray() { const array = []; for (const entry of this._array) array[entry.index] = entry.value; return array; } } exports.IndexMap = IndexMap; //# sourceMappingURL=IndexMap.js.map