massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-json / node_modules / vscode-jsonrpc / lib / common / linkedMap.js
1 "use strict";
2 /*---------------------------------------------------------------------------------------------
3  *  Copyright (c) Microsoft Corporation. All rights reserved.
4  *  Licensed under the MIT License. See License.txt in the project root for license information.
5  *--------------------------------------------------------------------------------------------*/
6 Object.defineProperty(exports, "__esModule", { value: true });
7 exports.LRUCache = exports.LinkedMap = exports.Touch = void 0;
8 var Touch;
9 (function (Touch) {
10     Touch.None = 0;
11     Touch.First = 1;
12     Touch.AsOld = Touch.First;
13     Touch.Last = 2;
14     Touch.AsNew = Touch.Last;
15 })(Touch = exports.Touch || (exports.Touch = {}));
16 class LinkedMap {
17     constructor() {
18         this[Symbol.toStringTag] = 'LinkedMap';
19         this._map = new Map();
20         this._head = undefined;
21         this._tail = undefined;
22         this._size = 0;
23         this._state = 0;
24     }
25     clear() {
26         this._map.clear();
27         this._head = undefined;
28         this._tail = undefined;
29         this._size = 0;
30         this._state++;
31     }
32     isEmpty() {
33         return !this._head && !this._tail;
34     }
35     get size() {
36         return this._size;
37     }
38     get first() {
39         var _a;
40         return (_a = this._head) === null || _a === void 0 ? void 0 : _a.value;
41     }
42     get last() {
43         var _a;
44         return (_a = this._tail) === null || _a === void 0 ? void 0 : _a.value;
45     }
46     has(key) {
47         return this._map.has(key);
48     }
49     get(key, touch = Touch.None) {
50         const item = this._map.get(key);
51         if (!item) {
52             return undefined;
53         }
54         if (touch !== Touch.None) {
55             this.touch(item, touch);
56         }
57         return item.value;
58     }
59     set(key, value, touch = Touch.None) {
60         let item = this._map.get(key);
61         if (item) {
62             item.value = value;
63             if (touch !== Touch.None) {
64                 this.touch(item, touch);
65             }
66         }
67         else {
68             item = { key, value, next: undefined, previous: undefined };
69             switch (touch) {
70                 case Touch.None:
71                     this.addItemLast(item);
72                     break;
73                 case Touch.First:
74                     this.addItemFirst(item);
75                     break;
76                 case Touch.Last:
77                     this.addItemLast(item);
78                     break;
79                 default:
80                     this.addItemLast(item);
81                     break;
82             }
83             this._map.set(key, item);
84             this._size++;
85         }
86         return this;
87     }
88     delete(key) {
89         return !!this.remove(key);
90     }
91     remove(key) {
92         const item = this._map.get(key);
93         if (!item) {
94             return undefined;
95         }
96         this._map.delete(key);
97         this.removeItem(item);
98         this._size--;
99         return item.value;
100     }
101     shift() {
102         if (!this._head && !this._tail) {
103             return undefined;
104         }
105         if (!this._head || !this._tail) {
106             throw new Error('Invalid list');
107         }
108         const item = this._head;
109         this._map.delete(item.key);
110         this.removeItem(item);
111         this._size--;
112         return item.value;
113     }
114     forEach(callbackfn, thisArg) {
115         const state = this._state;
116         let current = this._head;
117         while (current) {
118             if (thisArg) {
119                 callbackfn.bind(thisArg)(current.value, current.key, this);
120             }
121             else {
122                 callbackfn(current.value, current.key, this);
123             }
124             if (this._state !== state) {
125                 throw new Error(`LinkedMap got modified during iteration.`);
126             }
127             current = current.next;
128         }
129     }
130     keys() {
131         const map = this;
132         const state = this._state;
133         let current = this._head;
134         const iterator = {
135             [Symbol.iterator]() {
136                 return iterator;
137             },
138             next() {
139                 if (map._state !== state) {
140                     throw new Error(`LinkedMap got modified during iteration.`);
141                 }
142                 if (current) {
143                     const result = { value: current.key, done: false };
144                     current = current.next;
145                     return result;
146                 }
147                 else {
148                     return { value: undefined, done: true };
149                 }
150             }
151         };
152         return iterator;
153     }
154     values() {
155         const map = this;
156         const state = this._state;
157         let current = this._head;
158         const iterator = {
159             [Symbol.iterator]() {
160                 return iterator;
161             },
162             next() {
163                 if (map._state !== state) {
164                     throw new Error(`LinkedMap got modified during iteration.`);
165                 }
166                 if (current) {
167                     const result = { value: current.value, done: false };
168                     current = current.next;
169                     return result;
170                 }
171                 else {
172                     return { value: undefined, done: true };
173                 }
174             }
175         };
176         return iterator;
177     }
178     entries() {
179         const map = this;
180         const state = this._state;
181         let current = this._head;
182         const iterator = {
183             [Symbol.iterator]() {
184                 return iterator;
185             },
186             next() {
187                 if (map._state !== state) {
188                     throw new Error(`LinkedMap got modified during iteration.`);
189                 }
190                 if (current) {
191                     const result = { value: [current.key, current.value], done: false };
192                     current = current.next;
193                     return result;
194                 }
195                 else {
196                     return { value: undefined, done: true };
197                 }
198             }
199         };
200         return iterator;
201     }
202     [Symbol.iterator]() {
203         return this.entries();
204     }
205     trimOld(newSize) {
206         if (newSize >= this.size) {
207             return;
208         }
209         if (newSize === 0) {
210             this.clear();
211             return;
212         }
213         let current = this._head;
214         let currentSize = this.size;
215         while (current && currentSize > newSize) {
216             this._map.delete(current.key);
217             current = current.next;
218             currentSize--;
219         }
220         this._head = current;
221         this._size = currentSize;
222         if (current) {
223             current.previous = undefined;
224         }
225         this._state++;
226     }
227     addItemFirst(item) {
228         // First time Insert
229         if (!this._head && !this._tail) {
230             this._tail = item;
231         }
232         else if (!this._head) {
233             throw new Error('Invalid list');
234         }
235         else {
236             item.next = this._head;
237             this._head.previous = item;
238         }
239         this._head = item;
240         this._state++;
241     }
242     addItemLast(item) {
243         // First time Insert
244         if (!this._head && !this._tail) {
245             this._head = item;
246         }
247         else if (!this._tail) {
248             throw new Error('Invalid list');
249         }
250         else {
251             item.previous = this._tail;
252             this._tail.next = item;
253         }
254         this._tail = item;
255         this._state++;
256     }
257     removeItem(item) {
258         if (item === this._head && item === this._tail) {
259             this._head = undefined;
260             this._tail = undefined;
261         }
262         else if (item === this._head) {
263             // This can only happend if size === 1 which is handle
264             // by the case above.
265             if (!item.next) {
266                 throw new Error('Invalid list');
267             }
268             item.next.previous = undefined;
269             this._head = item.next;
270         }
271         else if (item === this._tail) {
272             // This can only happend if size === 1 which is handle
273             // by the case above.
274             if (!item.previous) {
275                 throw new Error('Invalid list');
276             }
277             item.previous.next = undefined;
278             this._tail = item.previous;
279         }
280         else {
281             const next = item.next;
282             const previous = item.previous;
283             if (!next || !previous) {
284                 throw new Error('Invalid list');
285             }
286             next.previous = previous;
287             previous.next = next;
288         }
289         item.next = undefined;
290         item.previous = undefined;
291         this._state++;
292     }
293     touch(item, touch) {
294         if (!this._head || !this._tail) {
295             throw new Error('Invalid list');
296         }
297         if ((touch !== Touch.First && touch !== Touch.Last)) {
298             return;
299         }
300         if (touch === Touch.First) {
301             if (item === this._head) {
302                 return;
303             }
304             const next = item.next;
305             const previous = item.previous;
306             // Unlink the item
307             if (item === this._tail) {
308                 // previous must be defined since item was not head but is tail
309                 // So there are more than on item in the map
310                 previous.next = undefined;
311                 this._tail = previous;
312             }
313             else {
314                 // Both next and previous are not undefined since item was neither head nor tail.
315                 next.previous = previous;
316                 previous.next = next;
317             }
318             // Insert the node at head
319             item.previous = undefined;
320             item.next = this._head;
321             this._head.previous = item;
322             this._head = item;
323             this._state++;
324         }
325         else if (touch === Touch.Last) {
326             if (item === this._tail) {
327                 return;
328             }
329             const next = item.next;
330             const previous = item.previous;
331             // Unlink the item.
332             if (item === this._head) {
333                 // next must be defined since item was not tail but is head
334                 // So there are more than on item in the map
335                 next.previous = undefined;
336                 this._head = next;
337             }
338             else {
339                 // Both next and previous are not undefined since item was neither head nor tail.
340                 next.previous = previous;
341                 previous.next = next;
342             }
343             item.next = undefined;
344             item.previous = this._tail;
345             this._tail.next = item;
346             this._tail = item;
347             this._state++;
348         }
349     }
350     toJSON() {
351         const data = [];
352         this.forEach((value, key) => {
353             data.push([key, value]);
354         });
355         return data;
356     }
357     fromJSON(data) {
358         this.clear();
359         for (const [key, value] of data) {
360             this.set(key, value);
361         }
362     }
363 }
364 exports.LinkedMap = LinkedMap;
365 class LRUCache extends LinkedMap {
366     constructor(limit, ratio = 1) {
367         super();
368         this._limit = limit;
369         this._ratio = Math.min(Math.max(0, ratio), 1);
370     }
371     get limit() {
372         return this._limit;
373     }
374     set limit(limit) {
375         this._limit = limit;
376         this.checkTrim();
377     }
378     get ratio() {
379         return this._ratio;
380     }
381     set ratio(ratio) {
382         this._ratio = Math.min(Math.max(0, ratio), 1);
383         this.checkTrim();
384     }
385     get(key, touch = Touch.AsNew) {
386         return super.get(key, touch);
387     }
388     peek(key) {
389         return super.get(key, Touch.None);
390     }
391     set(key, value) {
392         super.set(key, value, Touch.Last);
393         this.checkTrim();
394         return this;
395     }
396     checkTrim() {
397         if (this.size > this._limit) {
398             this.trimOld(Math.round(this._limit * this._ratio));
399         }
400     }
401 }
402 exports.LRUCache = LRUCache;
403 //# sourceMappingURL=linkedMap.js.map