initial commit
This commit is contained in:
403
node_modules/vscode-jsonrpc/lib/common/linkedMap.js
generated
vendored
Normal file
403
node_modules/vscode-jsonrpc/lib/common/linkedMap.js
generated
vendored
Normal file
@@ -0,0 +1,403 @@
|
||||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LRUCache = exports.LinkedMap = exports.Touch = void 0;
|
||||
var Touch;
|
||||
(function (Touch) {
|
||||
Touch.None = 0;
|
||||
Touch.First = 1;
|
||||
Touch.AsOld = Touch.First;
|
||||
Touch.Last = 2;
|
||||
Touch.AsNew = Touch.Last;
|
||||
})(Touch = exports.Touch || (exports.Touch = {}));
|
||||
class LinkedMap {
|
||||
constructor() {
|
||||
this[Symbol.toStringTag] = '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 _a;
|
||||
return (_a = this._head) === null || _a === void 0 ? void 0 : _a.value;
|
||||
}
|
||||
get last() {
|
||||
var _a;
|
||||
return (_a = this._tail) === null || _a === void 0 ? void 0 : _a.value;
|
||||
}
|
||||
has(key) {
|
||||
return this._map.has(key);
|
||||
}
|
||||
get(key, touch = Touch.None) {
|
||||
const item = this._map.get(key);
|
||||
if (!item) {
|
||||
return undefined;
|
||||
}
|
||||
if (touch !== Touch.None) {
|
||||
this.touch(item, touch);
|
||||
}
|
||||
return item.value;
|
||||
}
|
||||
set(key, value, touch = Touch.None) {
|
||||
let item = this._map.get(key);
|
||||
if (item) {
|
||||
item.value = value;
|
||||
if (touch !== Touch.None) {
|
||||
this.touch(item, touch);
|
||||
}
|
||||
}
|
||||
else {
|
||||
item = { key, value, next: undefined, previous: undefined };
|
||||
switch (touch) {
|
||||
case Touch.None:
|
||||
this.addItemLast(item);
|
||||
break;
|
||||
case Touch.First:
|
||||
this.addItemFirst(item);
|
||||
break;
|
||||
case Touch.Last:
|
||||
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;
|
||||
}
|
||||
[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 happend if size === 1 which is handle
|
||||
// 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 happend if size === 1 which is handle
|
||||
// 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 !== Touch.First && touch !== Touch.Last)) {
|
||||
return;
|
||||
}
|
||||
if (touch === Touch.First) {
|
||||
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 === Touch.Last) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.LinkedMap = LinkedMap;
|
||||
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 ratio() {
|
||||
return this._ratio;
|
||||
}
|
||||
set ratio(ratio) {
|
||||
this._ratio = Math.min(Math.max(0, ratio), 1);
|
||||
this.checkTrim();
|
||||
}
|
||||
get(key, touch = Touch.AsNew) {
|
||||
return super.get(key, touch);
|
||||
}
|
||||
peek(key) {
|
||||
return super.get(key, Touch.None);
|
||||
}
|
||||
set(key, value) {
|
||||
super.set(key, value, Touch.Last);
|
||||
this.checkTrim();
|
||||
return this;
|
||||
}
|
||||
checkTrim() {
|
||||
if (this.size > this._limit) {
|
||||
this.trimOld(Math.round(this._limit * this._ratio));
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.LRUCache = LRUCache;
|
||||
//# sourceMappingURL=linkedMap.js.map
|
||||
Reference in New Issue
Block a user