less memory, reduce timing verbosity

This commit is contained in:
Tobias Koppers 2019-07-26 08:02:30 +02:00
parent 126fb99121
commit 2e0ce0d1a9
1 changed files with 104 additions and 98 deletions

View File

@ -212,8 +212,11 @@ const visitModules = (
.reverse(); .reverse();
/** @type {Map<ChunkGroup, Set<ChunkGroup>>} */ /** @type {Map<ChunkGroup, Set<ChunkGroup>>} */
const queueConnect = new Map(); const queueConnect = new Map();
/** @type {Set<ChunkGroupInfo>} */
const outdatedChunkGroupInfo = new Set();
/** @type {QueueItem[]} */ /** @type {QueueItem[]} */
let queueDelayed = []; let queueDelayed = [];
logger.timeEnd("prepare"); logger.timeEnd("prepare");
/** @type {Module} */ /** @type {Module} */
@ -414,119 +417,122 @@ const visitModules = (
} }
} }
logger.timeEnd("visiting"); logger.timeEnd("visiting");
logger.time("calculating available modules");
/** @type {Set<ChunkGroupInfo>} */ if (queueConnect.size > 0) {
const outdatedChunkGroupInfo = new Set(); logger.time("calculating available modules");
// Figure out new parents for chunk groups // Figure out new parents for chunk groups
// to get new available modules for these children // to get new available modules for these children
for (const [chunkGroup, targets] of queueConnect) { for (const [chunkGroup, targets] of queueConnect) {
const info = chunkGroupInfoMap.get(chunkGroup); const info = chunkGroupInfoMap.get(chunkGroup);
let minAvailableModules = info.minAvailableModules; let minAvailableModules = info.minAvailableModules;
// 1. Create a new Set of available modules at this points // 1. Create a new Set of available modules at this points
const resultingAvailableModules = new Set(minAvailableModules); const resultingAvailableModules = new Set(minAvailableModules);
for (const chunk of chunkGroup.chunks) { for (const chunk of chunkGroup.chunks) {
for (const m of chunk.modulesIterable) { for (const m of chunk.modulesIterable) {
resultingAvailableModules.add(m); resultingAvailableModules.add(m);
}
}
info.resultingAvailableModules = resultingAvailableModules;
// 2. Update chunk group info
for (const target of targets) {
let chunkGroupInfo = chunkGroupInfoMap.get(target);
if (chunkGroupInfo === undefined) {
chunkGroupInfo = {
minAvailableModules: undefined,
minAvailableModulesOwned: undefined,
availableModulesToBeMerged: [],
skippedItems: [],
resultingAvailableModules: undefined
};
chunkGroupInfoMap.set(target, chunkGroupInfo);
}
chunkGroupInfo.availableModulesToBeMerged.push(
resultingAvailableModules
);
outdatedChunkGroupInfo.add(chunkGroupInfo);
} }
} }
info.resultingAvailableModules = resultingAvailableModules; queueConnect.clear();
logger.timeEnd("calculating available modules");
// 2. Update chunk group info if (outdatedChunkGroupInfo.size > 0) {
for (const target of targets) { logger.time("merging available modules");
let chunkGroupInfo = chunkGroupInfoMap.get(target); // Execute the merge
if (chunkGroupInfo === undefined) { for (const info of outdatedChunkGroupInfo) {
chunkGroupInfo = { const availableModulesToBeMerged = info.availableModulesToBeMerged;
minAvailableModules: undefined, let minAvailableModules = info.minAvailableModules;
minAvailableModulesOwned: undefined,
availableModulesToBeMerged: [],
skippedItems: [],
resultingAvailableModules: undefined
};
chunkGroupInfoMap.set(target, chunkGroupInfo);
}
chunkGroupInfo.availableModulesToBeMerged.push(
resultingAvailableModules
);
outdatedChunkGroupInfo.add(chunkGroupInfo);
}
}
queueConnect.clear();
logger.timeEnd("calculating available modules");
logger.time("merging available modules"); // 1. Get minimal available modules
// Execute the merge // It doesn't make sense to traverse a chunk again with more available modules.
for (const info of outdatedChunkGroupInfo) { // This step calculates the minimal available modules and skips traversal when
const availableModulesToBeMerged = info.availableModulesToBeMerged; // the list didn't shrink.
let minAvailableModules = info.minAvailableModules; if (availableModulesToBeMerged.length > 1) {
availableModulesToBeMerged.sort(bySetSize);
// 1. Get minimal available modules }
// It doesn't make sense to traverse a chunk again with more available modules. let changed = false;
// This step calculates the minimal available modules and skips traversal when for (const availableModules of availableModulesToBeMerged) {
// the list didn't shrink. if (minAvailableModules === undefined) {
if (availableModulesToBeMerged.length > 1) { minAvailableModules = availableModules;
availableModulesToBeMerged.sort(bySetSize); info.minAvailableModules = minAvailableModules;
} info.minAvailableModulesOwned = false;
let changed = false; changed = true;
for (const availableModules of availableModulesToBeMerged) { } else {
if (minAvailableModules === undefined) { if (info.minAvailableModulesOwned) {
minAvailableModules = availableModules; // We own it and can modify it
info.minAvailableModules = minAvailableModules; for (const m of minAvailableModules) {
info.minAvailableModulesOwned = false; if (!availableModules.has(m)) {
changed = true; minAvailableModules.delete(m);
} else { changed = true;
if (info.minAvailableModulesOwned) { }
// We own it and can modify it }
for (const m of minAvailableModules) { } else {
if (!availableModules.has(m)) { for (const m of minAvailableModules) {
minAvailableModules.delete(m); if (!availableModules.has(m)) {
changed = true; // minAvailableModules need to be modified
} // but we don't own it
} // construct a new Set as intersection of minAvailableModules and availableModules
} else { /** @type {Set<Module>} */
for (const m of minAvailableModules) { const newSet = new Set();
if (!availableModules.has(m)) { const iterator = minAvailableModules[Symbol.iterator]();
// minAvailableModules need to be modified /** @type {IteratorResult<Module>} */
// but we don't own it let it;
// construct a new Set as intersection of minAvailableModules and availableModules while (!(it = iterator.next()).done) {
/** @type {Set<Module>} */ const module = it.value;
const newSet = new Set(); if (module === m) break;
const iterator = minAvailableModules[Symbol.iterator](); newSet.add(module);
/** @type {IteratorResult<Module>} */ }
let it; while (!(it = iterator.next()).done) {
while (!(it = iterator.next()).done) { const module = it.value;
const module = it.value; if (availableModules.has(module)) {
if (module === m) break; newSet.add(module);
newSet.add(module); }
} }
while (!(it = iterator.next()).done) { minAvailableModules = newSet;
const module = it.value; info.minAvailableModulesOwned = true;
if (availableModules.has(module)) { info.minAvailableModules = newSet;
newSet.add(module); changed = true;
break;
} }
} }
minAvailableModules = newSet;
info.minAvailableModulesOwned = true;
info.minAvailableModules = newSet;
changed = true;
break;
} }
} }
} }
} availableModulesToBeMerged.length = 0;
} if (!changed) continue;
availableModulesToBeMerged.length = 0;
if (!changed) continue;
// 2. Reconsider skipped items // 2. Reconsider skipped items
for (const queueItem of info.skippedItems) { for (const queueItem of info.skippedItems) {
queue.push(queueItem); queue.push(queueItem);
}
info.skippedItems.length = 0;
}
outdatedChunkGroupInfo.clear();
logger.timeEnd("merging available modules");
} }
info.skippedItems.length = 0;
} }
logger.timeEnd("merging available modules");
// Run queueDelayed when all items of the queue are processed // Run queueDelayed when all items of the queue are processed
// This is important to get the global indicing correct // This is important to get the global indicing correct