| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- var _a, _b;
- import { compare, compareIgnoreCase, compareSubstring, compareSubstringIgnoreCase } from './strings.js';
- import { URI } from './uri.js';
- export class StringIterator {
- constructor() {
- this._value = '';
- this._pos = 0;
- }
- reset(key) {
- this._value = key;
- this._pos = 0;
- return this;
- }
- next() {
- this._pos += 1;
- return this;
- }
- hasNext() {
- return this._pos < this._value.length - 1;
- }
- cmp(a) {
- const aCode = a.charCodeAt(0);
- const thisCode = this._value.charCodeAt(this._pos);
- return aCode - thisCode;
- }
- value() {
- return this._value[this._pos];
- }
- }
- export class ConfigKeysIterator {
- constructor(_caseSensitive = true) {
- this._caseSensitive = _caseSensitive;
- }
- reset(key) {
- this._value = key;
- this._from = 0;
- this._to = 0;
- return this.next();
- }
- hasNext() {
- return this._to < this._value.length;
- }
- next() {
- // this._data = key.split(/[\\/]/).filter(s => !!s);
- this._from = this._to;
- let justSeps = true;
- for (; this._to < this._value.length; this._to++) {
- const ch = this._value.charCodeAt(this._to);
- if (ch === 46 /* Period */) {
- if (justSeps) {
- this._from++;
- }
- else {
- break;
- }
- }
- else {
- justSeps = false;
- }
- }
- return this;
- }
- cmp(a) {
- return this._caseSensitive
- ? compareSubstring(a, this._value, 0, a.length, this._from, this._to)
- : compareSubstringIgnoreCase(a, this._value, 0, a.length, this._from, this._to);
- }
- value() {
- return this._value.substring(this._from, this._to);
- }
- }
- export class PathIterator {
- constructor(_splitOnBackslash = true, _caseSensitive = true) {
- this._splitOnBackslash = _splitOnBackslash;
- this._caseSensitive = _caseSensitive;
- }
- reset(key) {
- this._value = key.replace(/\\$|\/$/, '');
- this._from = 0;
- this._to = 0;
- return this.next();
- }
- hasNext() {
- return this._to < this._value.length;
- }
- next() {
- // this._data = key.split(/[\\/]/).filter(s => !!s);
- this._from = this._to;
- let justSeps = true;
- for (; this._to < this._value.length; this._to++) {
- const ch = this._value.charCodeAt(this._to);
- if (ch === 47 /* Slash */ || this._splitOnBackslash && ch === 92 /* Backslash */) {
- if (justSeps) {
- this._from++;
- }
- else {
- break;
- }
- }
- else {
- justSeps = false;
- }
- }
- return this;
- }
- cmp(a) {
- return this._caseSensitive
- ? compareSubstring(a, this._value, 0, a.length, this._from, this._to)
- : compareSubstringIgnoreCase(a, this._value, 0, a.length, this._from, this._to);
- }
- value() {
- return this._value.substring(this._from, this._to);
- }
- }
- export class UriIterator {
- constructor(_ignorePathCasing) {
- this._ignorePathCasing = _ignorePathCasing;
- this._states = [];
- this._stateIdx = 0;
- }
- reset(key) {
- this._value = key;
- this._states = [];
- if (this._value.scheme) {
- this._states.push(1 /* Scheme */);
- }
- if (this._value.authority) {
- this._states.push(2 /* Authority */);
- }
- if (this._value.path) {
- this._pathIterator = new PathIterator(false, !this._ignorePathCasing(key));
- this._pathIterator.reset(key.path);
- if (this._pathIterator.value()) {
- this._states.push(3 /* Path */);
- }
- }
- if (this._value.query) {
- this._states.push(4 /* Query */);
- }
- if (this._value.fragment) {
- this._states.push(5 /* Fragment */);
- }
- this._stateIdx = 0;
- return this;
- }
- next() {
- if (this._states[this._stateIdx] === 3 /* Path */ && this._pathIterator.hasNext()) {
- this._pathIterator.next();
- }
- else {
- this._stateIdx += 1;
- }
- return this;
- }
- hasNext() {
- return (this._states[this._stateIdx] === 3 /* Path */ && this._pathIterator.hasNext())
- || this._stateIdx < this._states.length - 1;
- }
- cmp(a) {
- if (this._states[this._stateIdx] === 1 /* Scheme */) {
- return compareIgnoreCase(a, this._value.scheme);
- }
- else if (this._states[this._stateIdx] === 2 /* Authority */) {
- return compareIgnoreCase(a, this._value.authority);
- }
- else if (this._states[this._stateIdx] === 3 /* Path */) {
- return this._pathIterator.cmp(a);
- }
- else if (this._states[this._stateIdx] === 4 /* Query */) {
- return compare(a, this._value.query);
- }
- else if (this._states[this._stateIdx] === 5 /* Fragment */) {
- return compare(a, this._value.fragment);
- }
- throw new Error();
- }
- value() {
- if (this._states[this._stateIdx] === 1 /* Scheme */) {
- return this._value.scheme;
- }
- else if (this._states[this._stateIdx] === 2 /* Authority */) {
- return this._value.authority;
- }
- else if (this._states[this._stateIdx] === 3 /* Path */) {
- return this._pathIterator.value();
- }
- else if (this._states[this._stateIdx] === 4 /* Query */) {
- return this._value.query;
- }
- else if (this._states[this._stateIdx] === 5 /* Fragment */) {
- return this._value.fragment;
- }
- throw new Error();
- }
- }
- class TernarySearchTreeNode {
- isEmpty() {
- return !this.left && !this.mid && !this.right && !this.value;
- }
- }
- export class TernarySearchTree {
- constructor(segments) {
- this._iter = segments;
- }
- static forUris(ignorePathCasing = () => false) {
- return new TernarySearchTree(new UriIterator(ignorePathCasing));
- }
- static forStrings() {
- return new TernarySearchTree(new StringIterator());
- }
- static forConfigKeys() {
- return new TernarySearchTree(new ConfigKeysIterator());
- }
- clear() {
- this._root = undefined;
- }
- set(key, element) {
- const iter = this._iter.reset(key);
- let node;
- if (!this._root) {
- this._root = new TernarySearchTreeNode();
- this._root.segment = iter.value();
- }
- node = this._root;
- while (true) {
- const val = iter.cmp(node.segment);
- if (val > 0) {
- // left
- if (!node.left) {
- node.left = new TernarySearchTreeNode();
- node.left.segment = iter.value();
- }
- node = node.left;
- }
- else if (val < 0) {
- // right
- if (!node.right) {
- node.right = new TernarySearchTreeNode();
- node.right.segment = iter.value();
- }
- node = node.right;
- }
- else if (iter.hasNext()) {
- // mid
- iter.next();
- if (!node.mid) {
- node.mid = new TernarySearchTreeNode();
- node.mid.segment = iter.value();
- }
- node = node.mid;
- }
- else {
- break;
- }
- }
- const oldElement = node.value;
- node.value = element;
- node.key = key;
- return oldElement;
- }
- get(key) {
- var _c;
- return (_c = this._getNode(key)) === null || _c === void 0 ? void 0 : _c.value;
- }
- _getNode(key) {
- const iter = this._iter.reset(key);
- let node = this._root;
- while (node) {
- const val = iter.cmp(node.segment);
- if (val > 0) {
- // left
- node = node.left;
- }
- else if (val < 0) {
- // right
- node = node.right;
- }
- else if (iter.hasNext()) {
- // mid
- iter.next();
- node = node.mid;
- }
- else {
- break;
- }
- }
- return node;
- }
- has(key) {
- const node = this._getNode(key);
- return !((node === null || node === void 0 ? void 0 : node.value) === undefined && (node === null || node === void 0 ? void 0 : node.mid) === undefined);
- }
- delete(key) {
- return this._delete(key, false);
- }
- deleteSuperstr(key) {
- return this._delete(key, true);
- }
- _delete(key, superStr) {
- const iter = this._iter.reset(key);
- const stack = [];
- let node = this._root;
- // find and unset node
- while (node) {
- const val = iter.cmp(node.segment);
- if (val > 0) {
- // left
- stack.push([1, node]);
- node = node.left;
- }
- else if (val < 0) {
- // right
- stack.push([-1, node]);
- node = node.right;
- }
- else if (iter.hasNext()) {
- // mid
- iter.next();
- stack.push([0, node]);
- node = node.mid;
- }
- else {
- if (superStr) {
- // remove children
- node.left = undefined;
- node.mid = undefined;
- node.right = undefined;
- }
- else {
- // remove element
- node.value = undefined;
- }
- // clean up empty nodes
- while (stack.length > 0 && node.isEmpty()) {
- let [dir, parent] = stack.pop();
- switch (dir) {
- case 1:
- parent.left = undefined;
- break;
- case 0:
- parent.mid = undefined;
- break;
- case -1:
- parent.right = undefined;
- break;
- }
- node = parent;
- }
- break;
- }
- }
- }
- findSubstr(key) {
- const iter = this._iter.reset(key);
- let node = this._root;
- let candidate = undefined;
- while (node) {
- const val = iter.cmp(node.segment);
- if (val > 0) {
- // left
- node = node.left;
- }
- else if (val < 0) {
- // right
- node = node.right;
- }
- else if (iter.hasNext()) {
- // mid
- iter.next();
- candidate = node.value || candidate;
- node = node.mid;
- }
- else {
- break;
- }
- }
- return node && node.value || candidate;
- }
- findSuperstr(key) {
- const iter = this._iter.reset(key);
- let node = this._root;
- while (node) {
- const val = iter.cmp(node.segment);
- if (val > 0) {
- // left
- node = node.left;
- }
- else if (val < 0) {
- // right
- node = node.right;
- }
- else if (iter.hasNext()) {
- // mid
- iter.next();
- node = node.mid;
- }
- else {
- // collect
- if (!node.mid) {
- return undefined;
- }
- else {
- return this._entries(node.mid);
- }
- }
- }
- return undefined;
- }
- forEach(callback) {
- for (const [key, value] of this) {
- callback(value, key);
- }
- }
- *[Symbol.iterator]() {
- yield* this._entries(this._root);
- }
- *_entries(node) {
- // DFS
- if (!node) {
- return;
- }
- const stack = [node];
- while (stack.length > 0) {
- const node = stack.pop();
- if (node) {
- if (node.value) {
- yield [node.key, node.value];
- }
- if (node.left) {
- stack.push(node.left);
- }
- if (node.mid) {
- stack.push(node.mid);
- }
- if (node.right) {
- stack.push(node.right);
- }
- }
- }
- }
- }
- export class ResourceMap {
- constructor(mapOrKeyFn, toKey) {
- this[_a] = 'ResourceMap';
- if (mapOrKeyFn instanceof ResourceMap) {
- this.map = new Map(mapOrKeyFn.map);
- this.toKey = toKey !== null && toKey !== void 0 ? toKey : ResourceMap.defaultToKey;
- }
- else {
- this.map = new Map();
- this.toKey = mapOrKeyFn !== null && mapOrKeyFn !== void 0 ? mapOrKeyFn : ResourceMap.defaultToKey;
- }
- }
- set(resource, value) {
- this.map.set(this.toKey(resource), value);
- return this;
- }
- get(resource) {
- return this.map.get(this.toKey(resource));
- }
- has(resource) {
- return this.map.has(this.toKey(resource));
- }
- get size() {
- return this.map.size;
- }
- clear() {
- this.map.clear();
- }
- delete(resource) {
- return this.map.delete(this.toKey(resource));
- }
- forEach(clb, thisArg) {
- if (typeof thisArg !== 'undefined') {
- clb = clb.bind(thisArg);
- }
- for (let [index, value] of this.map) {
- clb(value, URI.parse(index), this);
- }
- }
- values() {
- return this.map.values();
- }
- *keys() {
- for (let key of this.map.keys()) {
- yield URI.parse(key);
- }
- }
- *entries() {
- for (let tuple of this.map.entries()) {
- yield [URI.parse(tuple[0]), tuple[1]];
- }
- }
- *[(_a = Symbol.toStringTag, Symbol.iterator)]() {
- for (let item of this.map) {
- yield [URI.parse(item[0]), item[1]];
- }
- }
- }
- ResourceMap.defaultToKey = (resource) => resource.toString();
- export class LinkedMap {
- constructor() {
- this[_b] = 'LinkedMap';
- this._map = new Map();
- this._head = undefined;
- this._tail = undefined;
- this._size = 0;
- this._state = 0;
- }
- clear() {
- this._map.clear();
- this._head = undefined;
- this._tail = undefined;
- this._size = 0;
- this._state++;
- }
- isEmpty() {
- return !this._head && !this._tail;
- }
- get size() {
- return this._size;
- }
- get first() {
- var _c;
- return (_c = this._head) === null || _c === void 0 ? void 0 : _c.value;
- }
- get last() {
- var _c;
- return (_c = this._tail) === null || _c === void 0 ? void 0 : _c.value;
- }
- has(key) {
- return this._map.has(key);
- }
- get(key, touch = 0 /* None */) {
- const item = this._map.get(key);
- if (!item) {
- return undefined;
- }
- if (touch !== 0 /* None */) {
- this.touch(item, touch);
- }
- return item.value;
- }
- set(key, value, touch = 0 /* None */) {
- let item = this._map.get(key);
- if (item) {
- item.value = value;
- if (touch !== 0 /* None */) {
- this.touch(item, touch);
- }
- }
- else {
- item = { key, value, next: undefined, previous: undefined };
- switch (touch) {
- case 0 /* None */:
- this.addItemLast(item);
- break;
- case 1 /* AsOld */:
- this.addItemFirst(item);
- break;
- case 2 /* AsNew */:
- this.addItemLast(item);
- break;
- default:
- this.addItemLast(item);
- break;
- }
- this._map.set(key, item);
- this._size++;
- }
- return this;
- }
- delete(key) {
- return !!this.remove(key);
- }
- remove(key) {
- const item = this._map.get(key);
- if (!item) {
- return undefined;
- }
- this._map.delete(key);
- this.removeItem(item);
- this._size--;
- return item.value;
- }
- shift() {
- if (!this._head && !this._tail) {
- return undefined;
- }
- if (!this._head || !this._tail) {
- throw new Error('Invalid list');
- }
- const item = this._head;
- this._map.delete(item.key);
- this.removeItem(item);
- this._size--;
- return item.value;
- }
- forEach(callbackfn, thisArg) {
- const state = this._state;
- let current = this._head;
- while (current) {
- if (thisArg) {
- callbackfn.bind(thisArg)(current.value, current.key, this);
- }
- else {
- callbackfn(current.value, current.key, this);
- }
- if (this._state !== state) {
- throw new Error(`LinkedMap got modified during iteration.`);
- }
- current = current.next;
- }
- }
- keys() {
- const map = this;
- const state = this._state;
- let current = this._head;
- const iterator = {
- [Symbol.iterator]() {
- return iterator;
- },
- next() {
- if (map._state !== state) {
- throw new Error(`LinkedMap got modified during iteration.`);
- }
- if (current) {
- const result = { value: current.key, done: false };
- current = current.next;
- return result;
- }
- else {
- return { value: undefined, done: true };
- }
- }
- };
- return iterator;
- }
- values() {
- const map = this;
- const state = this._state;
- let current = this._head;
- const iterator = {
- [Symbol.iterator]() {
- return iterator;
- },
- next() {
- if (map._state !== state) {
- throw new Error(`LinkedMap got modified during iteration.`);
- }
- if (current) {
- const result = { value: current.value, done: false };
- current = current.next;
- return result;
- }
- else {
- return { value: undefined, done: true };
- }
- }
- };
- return iterator;
- }
- entries() {
- const map = this;
- const state = this._state;
- let current = this._head;
- const iterator = {
- [Symbol.iterator]() {
- return iterator;
- },
- next() {
- if (map._state !== state) {
- throw new Error(`LinkedMap got modified during iteration.`);
- }
- if (current) {
- const result = { value: [current.key, current.value], done: false };
- current = current.next;
- return result;
- }
- else {
- return { value: undefined, done: true };
- }
- }
- };
- return iterator;
- }
- [(_b = Symbol.toStringTag, Symbol.iterator)]() {
- return this.entries();
- }
- trimOld(newSize) {
- if (newSize >= this.size) {
- return;
- }
- if (newSize === 0) {
- this.clear();
- return;
- }
- let current = this._head;
- let currentSize = this.size;
- while (current && currentSize > newSize) {
- this._map.delete(current.key);
- current = current.next;
- currentSize--;
- }
- this._head = current;
- this._size = currentSize;
- if (current) {
- current.previous = undefined;
- }
- this._state++;
- }
- addItemFirst(item) {
- // First time Insert
- if (!this._head && !this._tail) {
- this._tail = item;
- }
- else if (!this._head) {
- throw new Error('Invalid list');
- }
- else {
- item.next = this._head;
- this._head.previous = item;
- }
- this._head = item;
- this._state++;
- }
- addItemLast(item) {
- // First time Insert
- if (!this._head && !this._tail) {
- this._head = item;
- }
- else if (!this._tail) {
- throw new Error('Invalid list');
- }
- else {
- item.previous = this._tail;
- this._tail.next = item;
- }
- this._tail = item;
- this._state++;
- }
- removeItem(item) {
- if (item === this._head && item === this._tail) {
- this._head = undefined;
- this._tail = undefined;
- }
- else if (item === this._head) {
- // This can only happen if size === 1 which is handled
- // by the case above.
- if (!item.next) {
- throw new Error('Invalid list');
- }
- item.next.previous = undefined;
- this._head = item.next;
- }
- else if (item === this._tail) {
- // This can only happen if size === 1 which is handled
- // by the case above.
- if (!item.previous) {
- throw new Error('Invalid list');
- }
- item.previous.next = undefined;
- this._tail = item.previous;
- }
- else {
- const next = item.next;
- const previous = item.previous;
- if (!next || !previous) {
- throw new Error('Invalid list');
- }
- next.previous = previous;
- previous.next = next;
- }
- item.next = undefined;
- item.previous = undefined;
- this._state++;
- }
- touch(item, touch) {
- if (!this._head || !this._tail) {
- throw new Error('Invalid list');
- }
- if ((touch !== 1 /* AsOld */ && touch !== 2 /* AsNew */)) {
- return;
- }
- if (touch === 1 /* AsOld */) {
- if (item === this._head) {
- return;
- }
- const next = item.next;
- const previous = item.previous;
- // Unlink the item
- if (item === this._tail) {
- // previous must be defined since item was not head but is tail
- // So there are more than on item in the map
- previous.next = undefined;
- this._tail = previous;
- }
- else {
- // Both next and previous are not undefined since item was neither head nor tail.
- next.previous = previous;
- previous.next = next;
- }
- // Insert the node at head
- item.previous = undefined;
- item.next = this._head;
- this._head.previous = item;
- this._head = item;
- this._state++;
- }
- else if (touch === 2 /* AsNew */) {
- if (item === this._tail) {
- return;
- }
- const next = item.next;
- const previous = item.previous;
- // Unlink the item.
- if (item === this._head) {
- // next must be defined since item was not tail but is head
- // So there are more than on item in the map
- next.previous = undefined;
- this._head = next;
- }
- else {
- // Both next and previous are not undefined since item was neither head nor tail.
- next.previous = previous;
- previous.next = next;
- }
- item.next = undefined;
- item.previous = this._tail;
- this._tail.next = item;
- this._tail = item;
- this._state++;
- }
- }
- toJSON() {
- const data = [];
- this.forEach((value, key) => {
- data.push([key, value]);
- });
- return data;
- }
- fromJSON(data) {
- this.clear();
- for (const [key, value] of data) {
- this.set(key, value);
- }
- }
- }
- export class LRUCache extends LinkedMap {
- constructor(limit, ratio = 1) {
- super();
- this._limit = limit;
- this._ratio = Math.min(Math.max(0, ratio), 1);
- }
- get limit() {
- return this._limit;
- }
- set limit(limit) {
- this._limit = limit;
- this.checkTrim();
- }
- get(key, touch = 2 /* AsNew */) {
- return super.get(key, touch);
- }
- peek(key) {
- return super.get(key, 0 /* None */);
- }
- set(key, value) {
- super.set(key, value, 2 /* AsNew */);
- this.checkTrim();
- return this;
- }
- checkTrim() {
- if (this.size > this._limit) {
- this.trimOld(Math.round(this._limit * this._ratio));
- }
- }
- }
|