source: frontend/node_modules/@alloc/quick-lru/index.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 5.2 KB
Line 
1'use strict';
2
3class QuickLRU {
4 constructor(options = {}) {
5 if (!(options.maxSize && options.maxSize > 0)) {
6 throw new TypeError('`maxSize` must be a number greater than 0');
7 }
8
9 if (typeof options.maxAge === 'number' && options.maxAge === 0) {
10 throw new TypeError('`maxAge` must be a number greater than 0');
11 }
12
13 this.maxSize = options.maxSize;
14 this.maxAge = options.maxAge || Infinity;
15 this.onEviction = options.onEviction;
16 this.cache = new Map();
17 this.oldCache = new Map();
18 this._size = 0;
19 }
20
21 _emitEvictions(cache) {
22 if (typeof this.onEviction !== 'function') {
23 return;
24 }
25
26 for (const [key, item] of cache) {
27 this.onEviction(key, item.value);
28 }
29 }
30
31 _deleteIfExpired(key, item) {
32 if (typeof item.expiry === 'number' && item.expiry <= Date.now()) {
33 if (typeof this.onEviction === 'function') {
34 this.onEviction(key, item.value);
35 }
36
37 return this.delete(key);
38 }
39
40 return false;
41 }
42
43 _getOrDeleteIfExpired(key, item) {
44 const deleted = this._deleteIfExpired(key, item);
45 if (deleted === false) {
46 return item.value;
47 }
48 }
49
50 _getItemValue(key, item) {
51 return item.expiry ? this._getOrDeleteIfExpired(key, item) : item.value;
52 }
53
54 _peek(key, cache) {
55 const item = cache.get(key);
56
57 return this._getItemValue(key, item);
58 }
59
60 _set(key, value) {
61 this.cache.set(key, value);
62 this._size++;
63
64 if (this._size >= this.maxSize) {
65 this._size = 0;
66 this._emitEvictions(this.oldCache);
67 this.oldCache = this.cache;
68 this.cache = new Map();
69 }
70 }
71
72 _moveToRecent(key, item) {
73 this.oldCache.delete(key);
74 this._set(key, item);
75 }
76
77 * _entriesAscending() {
78 for (const item of this.oldCache) {
79 const [key, value] = item;
80 if (!this.cache.has(key)) {
81 const deleted = this._deleteIfExpired(key, value);
82 if (deleted === false) {
83 yield item;
84 }
85 }
86 }
87
88 for (const item of this.cache) {
89 const [key, value] = item;
90 const deleted = this._deleteIfExpired(key, value);
91 if (deleted === false) {
92 yield item;
93 }
94 }
95 }
96
97 get(key) {
98 if (this.cache.has(key)) {
99 const item = this.cache.get(key);
100
101 return this._getItemValue(key, item);
102 }
103
104 if (this.oldCache.has(key)) {
105 const item = this.oldCache.get(key);
106 if (this._deleteIfExpired(key, item) === false) {
107 this._moveToRecent(key, item);
108 return item.value;
109 }
110 }
111 }
112
113 set(key, value, {maxAge = this.maxAge === Infinity ? undefined : Date.now() + this.maxAge} = {}) {
114 if (this.cache.has(key)) {
115 this.cache.set(key, {
116 value,
117 maxAge
118 });
119 } else {
120 this._set(key, {value, expiry: maxAge});
121 }
122 }
123
124 has(key) {
125 if (this.cache.has(key)) {
126 return !this._deleteIfExpired(key, this.cache.get(key));
127 }
128
129 if (this.oldCache.has(key)) {
130 return !this._deleteIfExpired(key, this.oldCache.get(key));
131 }
132
133 return false;
134 }
135
136 peek(key) {
137 if (this.cache.has(key)) {
138 return this._peek(key, this.cache);
139 }
140
141 if (this.oldCache.has(key)) {
142 return this._peek(key, this.oldCache);
143 }
144 }
145
146 delete(key) {
147 const deleted = this.cache.delete(key);
148 if (deleted) {
149 this._size--;
150 }
151
152 return this.oldCache.delete(key) || deleted;
153 }
154
155 clear() {
156 this.cache.clear();
157 this.oldCache.clear();
158 this._size = 0;
159 }
160
161 resize(newSize) {
162 if (!(newSize && newSize > 0)) {
163 throw new TypeError('`maxSize` must be a number greater than 0');
164 }
165
166 const items = [...this._entriesAscending()];
167 const removeCount = items.length - newSize;
168 if (removeCount < 0) {
169 this.cache = new Map(items);
170 this.oldCache = new Map();
171 this._size = items.length;
172 } else {
173 if (removeCount > 0) {
174 this._emitEvictions(items.slice(0, removeCount));
175 }
176
177 this.oldCache = new Map(items.slice(removeCount));
178 this.cache = new Map();
179 this._size = 0;
180 }
181
182 this.maxSize = newSize;
183 }
184
185 * keys() {
186 for (const [key] of this) {
187 yield key;
188 }
189 }
190
191 * values() {
192 for (const [, value] of this) {
193 yield value;
194 }
195 }
196
197 * [Symbol.iterator]() {
198 for (const item of this.cache) {
199 const [key, value] = item;
200 const deleted = this._deleteIfExpired(key, value);
201 if (deleted === false) {
202 yield [key, value.value];
203 }
204 }
205
206 for (const item of this.oldCache) {
207 const [key, value] = item;
208 if (!this.cache.has(key)) {
209 const deleted = this._deleteIfExpired(key, value);
210 if (deleted === false) {
211 yield [key, value.value];
212 }
213 }
214 }
215 }
216
217 * entriesDescending() {
218 let items = [...this.cache];
219 for (let i = items.length - 1; i >= 0; --i) {
220 const item = items[i];
221 const [key, value] = item;
222 const deleted = this._deleteIfExpired(key, value);
223 if (deleted === false) {
224 yield [key, value.value];
225 }
226 }
227
228 items = [...this.oldCache];
229 for (let i = items.length - 1; i >= 0; --i) {
230 const item = items[i];
231 const [key, value] = item;
232 if (!this.cache.has(key)) {
233 const deleted = this._deleteIfExpired(key, value);
234 if (deleted === false) {
235 yield [key, value.value];
236 }
237 }
238 }
239 }
240
241 * entriesAscending() {
242 for (const [key, value] of this._entriesAscending()) {
243 yield [key, value.value];
244 }
245 }
246
247 get size() {
248 if (!this._size) {
249 return this.oldCache.size;
250 }
251
252 let oldCacheSize = 0;
253 for (const key of this.oldCache.keys()) {
254 if (!this.cache.has(key)) {
255 oldCacheSize++;
256 }
257 }
258
259 return Math.min(this._size + oldCacheSize, this.maxSize);
260 }
261}
262
263module.exports = QuickLRU;
Note: See TracBrowser for help on using the repository browser.