Skip to content

Commit

Permalink
less memory, reduce timing verbosity
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Jul 26, 2019
1 parent 126fb99 commit 2e0ce0d
Showing 1 changed file with 104 additions and 98 deletions.
202 changes: 104 additions & 98 deletions lib/buildChunkGraph.js
Expand Up @@ -212,8 +212,11 @@ const visitModules = (
.reverse();
/** @type {Map<ChunkGroup, Set<ChunkGroup>>} */
const queueConnect = new Map();
/** @type {Set<ChunkGroupInfo>} */
const outdatedChunkGroupInfo = new Set();
/** @type {QueueItem[]} */
let queueDelayed = [];

logger.timeEnd("prepare");

/** @type {Module} */
Expand Down Expand Up @@ -414,119 +417,122 @@ const visitModules = (
}
}
logger.timeEnd("visiting");
logger.time("calculating available modules");

/** @type {Set<ChunkGroupInfo>} */
const outdatedChunkGroupInfo = new Set();
if (queueConnect.size > 0) {
logger.time("calculating available modules");

// Figure out new parents for chunk groups
// to get new available modules for these children
for (const [chunkGroup, targets] of queueConnect) {
const info = chunkGroupInfoMap.get(chunkGroup);
let minAvailableModules = info.minAvailableModules;
// Figure out new parents for chunk groups
// to get new available modules for these children
for (const [chunkGroup, targets] of queueConnect) {
const info = chunkGroupInfoMap.get(chunkGroup);
let minAvailableModules = info.minAvailableModules;

// 1. Create a new Set of available modules at this points
const resultingAvailableModules = new Set(minAvailableModules);
for (const chunk of chunkGroup.chunks) {
for (const m of chunk.modulesIterable) {
resultingAvailableModules.add(m);
// 1. Create a new Set of available modules at this points
const resultingAvailableModules = new Set(minAvailableModules);
for (const chunk of chunkGroup.chunks) {
for (const m of chunk.modulesIterable) {
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);
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);
}
chunkGroupInfo.availableModulesToBeMerged.push(
resultingAvailableModules
);
outdatedChunkGroupInfo.add(chunkGroupInfo);
}
}
queueConnect.clear();
logger.timeEnd("calculating available modules");

logger.time("merging available modules");
// Execute the merge
for (const info of outdatedChunkGroupInfo) {
const availableModulesToBeMerged = info.availableModulesToBeMerged;
let minAvailableModules = info.minAvailableModules;

// 1. Get minimal available modules
// It doesn't make sense to traverse a chunk again with more available modules.
// This step calculates the minimal available modules and skips traversal when
// the list didn't shrink.
if (availableModulesToBeMerged.length > 1) {
availableModulesToBeMerged.sort(bySetSize);
}
let changed = false;
for (const availableModules of availableModulesToBeMerged) {
if (minAvailableModules === undefined) {
minAvailableModules = availableModules;
info.minAvailableModules = minAvailableModules;
info.minAvailableModulesOwned = false;
changed = true;
} else {
if (info.minAvailableModulesOwned) {
// We own it and can modify it
for (const m of minAvailableModules) {
if (!availableModules.has(m)) {
minAvailableModules.delete(m);
changed = true;
}
}
} else {
for (const m of minAvailableModules) {
if (!availableModules.has(m)) {
// minAvailableModules need to be modified
// but we don't own it
// construct a new Set as intersection of minAvailableModules and availableModules
/** @type {Set<Module>} */
const newSet = new Set();
const iterator = minAvailableModules[Symbol.iterator]();
/** @type {IteratorResult<Module>} */
let it;
while (!(it = iterator.next()).done) {
const module = it.value;
if (module === m) break;
newSet.add(module);
queueConnect.clear();
logger.timeEnd("calculating available modules");

if (outdatedChunkGroupInfo.size > 0) {
logger.time("merging available modules");
// Execute the merge
for (const info of outdatedChunkGroupInfo) {
const availableModulesToBeMerged = info.availableModulesToBeMerged;
let minAvailableModules = info.minAvailableModules;

// 1. Get minimal available modules
// It doesn't make sense to traverse a chunk again with more available modules.
// This step calculates the minimal available modules and skips traversal when
// the list didn't shrink.
if (availableModulesToBeMerged.length > 1) {
availableModulesToBeMerged.sort(bySetSize);
}
let changed = false;
for (const availableModules of availableModulesToBeMerged) {
if (minAvailableModules === undefined) {
minAvailableModules = availableModules;
info.minAvailableModules = minAvailableModules;
info.minAvailableModulesOwned = false;
changed = true;
} else {
if (info.minAvailableModulesOwned) {
// We own it and can modify it
for (const m of minAvailableModules) {
if (!availableModules.has(m)) {
minAvailableModules.delete(m);
changed = true;
}
}
while (!(it = iterator.next()).done) {
const module = it.value;
if (availableModules.has(module)) {
newSet.add(module);
} else {
for (const m of minAvailableModules) {
if (!availableModules.has(m)) {
// minAvailableModules need to be modified
// but we don't own it
// construct a new Set as intersection of minAvailableModules and availableModules
/** @type {Set<Module>} */
const newSet = new Set();
const iterator = minAvailableModules[Symbol.iterator]();
/** @type {IteratorResult<Module>} */
let it;
while (!(it = iterator.next()).done) {
const module = it.value;
if (module === m) break;
newSet.add(module);
}
while (!(it = iterator.next()).done) {
const module = it.value;
if (availableModules.has(module)) {
newSet.add(module);
}
}
minAvailableModules = newSet;
info.minAvailableModulesOwned = true;
info.minAvailableModules = newSet;
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
for (const queueItem of info.skippedItems) {
queue.push(queueItem);
// 2. Reconsider skipped items
for (const queueItem of info.skippedItems) {
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
// This is important to get the global indicing correct
Expand Down

0 comments on commit 2e0ce0d

Please sign in to comment.