| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 | 
							- /*
 
- 	MIT License http://www.opensource.org/licenses/mit-license.php
 
- 	Author Tobias Koppers @sokra
 
- */
 
- "use strict";
 
- class FlagIncludedChunksPlugin {
 
- 	apply(compiler) {
 
- 		compiler.hooks.compilation.tap("FlagIncludedChunksPlugin", compilation => {
 
- 			compilation.hooks.optimizeChunkIds.tap(
 
- 				"FlagIncludedChunksPlugin",
 
- 				chunks => {
 
- 					// prepare two bit integers for each module
 
- 					// 2^31 is the max number represented as SMI in v8
 
- 					// we want the bits distributed this way:
 
- 					// the bit 2^31 is pretty rar and only one module should get it
 
- 					// so it has a probability of 1 / modulesCount
 
- 					// the first bit (2^0) is the easiest and every module could get it
 
- 					// if it doesn't get a better bit
 
- 					// from bit 2^n to 2^(n+1) there is a probability of p
 
- 					// so 1 / modulesCount == p^31
 
- 					// <=> p = sqrt31(1 / modulesCount)
 
- 					// so we use a modulo of 1 / sqrt31(1 / modulesCount)
 
- 					const moduleBits = new WeakMap();
 
- 					const modulesCount = compilation.modules.length;
 
- 					// precalculate the modulo values for each bit
 
- 					const modulo = 1 / Math.pow(1 / modulesCount, 1 / 31);
 
- 					const modulos = Array.from(
 
- 						{ length: 31 },
 
- 						(x, i) => Math.pow(modulo, i) | 0
 
- 					);
 
- 					// iterate all modules to generate bit values
 
- 					let i = 0;
 
- 					for (const module of compilation.modules) {
 
- 						let bit = 30;
 
- 						while (i % modulos[bit] !== 0) {
 
- 							bit--;
 
- 						}
 
- 						moduleBits.set(module, 1 << bit);
 
- 						i++;
 
- 					}
 
- 					// interate all chunks to generate bitmaps
 
- 					const chunkModulesHash = new WeakMap();
 
- 					for (const chunk of chunks) {
 
- 						let hash = 0;
 
- 						for (const module of chunk.modulesIterable) {
 
- 							hash |= moduleBits.get(module);
 
- 						}
 
- 						chunkModulesHash.set(chunk, hash);
 
- 					}
 
- 					for (const chunkA of chunks) {
 
- 						const chunkAHash = chunkModulesHash.get(chunkA);
 
- 						const chunkAModulesCount = chunkA.getNumberOfModules();
 
- 						if (chunkAModulesCount === 0) continue;
 
- 						let bestModule = undefined;
 
- 						for (const module of chunkA.modulesIterable) {
 
- 							if (
 
- 								bestModule === undefined ||
 
- 								bestModule.getNumberOfChunks() > module.getNumberOfChunks()
 
- 							)
 
- 								bestModule = module;
 
- 						}
 
- 						loopB: for (const chunkB of bestModule.chunksIterable) {
 
- 							// as we iterate the same iterables twice
 
- 							// skip if we find ourselves
 
- 							if (chunkA === chunkB) continue;
 
- 							const chunkBModulesCount = chunkB.getNumberOfModules();
 
- 							// ids for empty chunks are not included
 
- 							if (chunkBModulesCount === 0) continue;
 
- 							// instead of swapping A and B just bail
 
- 							// as we loop twice the current A will be B and B then A
 
- 							if (chunkAModulesCount > chunkBModulesCount) continue;
 
- 							// is chunkA in chunkB?
 
- 							// we do a cheap check for the hash value
 
- 							const chunkBHash = chunkModulesHash.get(chunkB);
 
- 							if ((chunkBHash & chunkAHash) !== chunkAHash) continue;
 
- 							// compare all modules
 
- 							for (const m of chunkA.modulesIterable) {
 
- 								if (!chunkB.containsModule(m)) continue loopB;
 
- 							}
 
- 							chunkB.ids.push(chunkA.id);
 
- 						}
 
- 					}
 
- 				}
 
- 			);
 
- 		});
 
- 	}
 
- }
 
- module.exports = FlagIncludedChunksPlugin;
 
 
  |