source: imaps-frontend/node_modules/webpack/lib/util/StackedMap.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 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
8const TOMBSTONE = Symbol("tombstone");
9const UNDEFINED_MARKER = Symbol("undefined");
10
11/**
12 * @template T
13 * @typedef {T | undefined} Cell<T>
14 */
15
16/**
17 * @template T
18 * @typedef {T | typeof TOMBSTONE | typeof UNDEFINED_MARKER} InternalCell<T>
19 */
20
21/**
22 * @template K
23 * @template V
24 * @param {[K, InternalCell<V>]} pair the internal cell
25 * @returns {[K, Cell<V>]} its “safe” representation
26 */
27const extractPair = pair => {
28 const key = pair[0];
29 const val = pair[1];
30 if (val === UNDEFINED_MARKER || val === TOMBSTONE) {
31 return [key, undefined];
32 }
33 return /** @type {[K, Cell<V>]} */ (pair);
34};
35
36/**
37 * @template K
38 * @template V
39 */
40class StackedMap {
41 /**
42 * @param {Map<K, InternalCell<V>>[]=} parentStack an optional parent
43 */
44 constructor(parentStack) {
45 /** @type {Map<K, InternalCell<V>>} */
46 this.map = new Map();
47 /** @type {Map<K, InternalCell<V>>[]} */
48 this.stack = parentStack === undefined ? [] : parentStack.slice();
49 this.stack.push(this.map);
50 }
51
52 /**
53 * @param {K} item the key of the element to add
54 * @param {V} value the value of the element to add
55 * @returns {void}
56 */
57 set(item, value) {
58 this.map.set(item, value === undefined ? UNDEFINED_MARKER : value);
59 }
60
61 /**
62 * @param {K} item the item to delete
63 * @returns {void}
64 */
65 delete(item) {
66 if (this.stack.length > 1) {
67 this.map.set(item, TOMBSTONE);
68 } else {
69 this.map.delete(item);
70 }
71 }
72
73 /**
74 * @param {K} item the item to test
75 * @returns {boolean} true if the item exists in this set
76 */
77 has(item) {
78 const topValue = this.map.get(item);
79 if (topValue !== undefined) {
80 return topValue !== TOMBSTONE;
81 }
82 if (this.stack.length > 1) {
83 for (let i = this.stack.length - 2; i >= 0; i--) {
84 const value = this.stack[i].get(item);
85 if (value !== undefined) {
86 this.map.set(item, value);
87 return value !== TOMBSTONE;
88 }
89 }
90 this.map.set(item, TOMBSTONE);
91 }
92 return false;
93 }
94
95 /**
96 * @param {K} item the key of the element to return
97 * @returns {Cell<V>} the value of the element
98 */
99 get(item) {
100 const topValue = this.map.get(item);
101 if (topValue !== undefined) {
102 return topValue === TOMBSTONE || topValue === UNDEFINED_MARKER
103 ? undefined
104 : topValue;
105 }
106 if (this.stack.length > 1) {
107 for (let i = this.stack.length - 2; i >= 0; i--) {
108 const value = this.stack[i].get(item);
109 if (value !== undefined) {
110 this.map.set(item, value);
111 return value === TOMBSTONE || value === UNDEFINED_MARKER
112 ? undefined
113 : value;
114 }
115 }
116 this.map.set(item, TOMBSTONE);
117 }
118 }
119
120 _compress() {
121 if (this.stack.length === 1) return;
122 this.map = new Map();
123 for (const data of this.stack) {
124 for (const pair of data) {
125 if (pair[1] === TOMBSTONE) {
126 this.map.delete(pair[0]);
127 } else {
128 this.map.set(pair[0], pair[1]);
129 }
130 }
131 }
132 this.stack = [this.map];
133 }
134
135 asArray() {
136 this._compress();
137 return Array.from(this.map.keys());
138 }
139
140 asSet() {
141 this._compress();
142 return new Set(this.map.keys());
143 }
144
145 asPairArray() {
146 this._compress();
147 return Array.from(this.map.entries(), extractPair);
148 }
149
150 asMap() {
151 return new Map(this.asPairArray());
152 }
153
154 get size() {
155 this._compress();
156 return this.map.size;
157 }
158
159 createChild() {
160 return new StackedMap(this.stack);
161 }
162}
163
164module.exports = StackedMap;
Note: See TracBrowser for help on using the repository browser.