source: imaps-frontend/node_modules/webpack/lib/util/StackedCacheMap.js

main
Last change on this file was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8/**
9 * The StackedCacheMap is a data structure designed as an alternative to a Map
10 * in situations where you need to handle multiple item additions and
11 * frequently access the largest map.
12 *
13 * It is particularly optimized for efficiently adding multiple items
14 * at once, which can be achieved using the `addAll` method.
15 *
16 * It has a fallback Map that is used when the map to be added is mutable.
17 *
18 * Note: `delete` and `has` are not supported for performance reasons.
19 * @example
20 * ```js
21 * const map = new StackedCacheMap();
22 * map.addAll(new Map([["a", 1], ["b", 2]]), true);
23 * map.addAll(new Map([["c", 3], ["d", 4]]), true);
24 * map.get("a"); // 1
25 * map.get("d"); // 4
26 * for (const [key, value] of map) {
27 * console.log(key, value);
28 * }
29 * ```
30 * @template K
31 * @template V
32 */
33class StackedCacheMap {
34 constructor() {
35 /** @type {Map<K, V>} */
36 this.map = new Map();
37 /** @type {ReadonlyMap<K, V>[]} */
38 this.stack = [];
39 }
40
41 /**
42 * If `immutable` is true, the map can be referenced by the StackedCacheMap
43 * and should not be changed afterwards. If the map is mutable, all items
44 * are copied into a fallback Map.
45 * @param {ReadonlyMap<K, V>} map map to add
46 * @param {boolean=} immutable if 'map' is immutable and StackedCacheMap can keep referencing it
47 */
48 addAll(map, immutable) {
49 if (immutable) {
50 this.stack.push(map);
51
52 // largest map should go first
53 for (let i = this.stack.length - 1; i > 0; i--) {
54 const beforeLast = this.stack[i - 1];
55 if (beforeLast.size >= map.size) break;
56 this.stack[i] = beforeLast;
57 this.stack[i - 1] = map;
58 }
59 } else {
60 for (const [key, value] of map) {
61 this.map.set(key, value);
62 }
63 }
64 }
65
66 /**
67 * @param {K} item the key of the element to add
68 * @param {V} value the value of the element to add
69 * @returns {void}
70 */
71 set(item, value) {
72 this.map.set(item, value);
73 }
74
75 /**
76 * @param {K} item the item to delete
77 * @returns {void}
78 */
79 delete(item) {
80 throw new Error("Items can't be deleted from a StackedCacheMap");
81 }
82
83 /**
84 * @param {K} item the item to test
85 * @returns {boolean} true if the item exists in this set
86 */
87 has(item) {
88 throw new Error(
89 "Checking StackedCacheMap.has before reading is inefficient, use StackedCacheMap.get and check for undefined"
90 );
91 }
92
93 /**
94 * @param {K} item the key of the element to return
95 * @returns {V | undefined} the value of the element
96 */
97 get(item) {
98 for (const map of this.stack) {
99 const value = map.get(item);
100 if (value !== undefined) return value;
101 }
102 return this.map.get(item);
103 }
104
105 clear() {
106 this.stack.length = 0;
107 this.map.clear();
108 }
109
110 /**
111 * @returns {number} size of the map
112 */
113 get size() {
114 let size = this.map.size;
115 for (const map of this.stack) {
116 size += map.size;
117 }
118 return size;
119 }
120
121 /**
122 * @returns {Iterator<[K, V]>} iterator
123 */
124 [Symbol.iterator]() {
125 const iterators = this.stack.map(map => map[Symbol.iterator]());
126 let current = this.map[Symbol.iterator]();
127 return {
128 next() {
129 let result = current.next();
130 while (result.done && iterators.length > 0) {
131 current = /** @type {IterableIterator<[K, V]>} */ (iterators.pop());
132 result = current.next();
133 }
134 return result;
135 }
136 };
137 }
138}
139
140module.exports = StackedCacheMap;
Note: See TracBrowser for help on using the repository browser.