Skip to content

Commit

Permalink
perf: merge backing timestamp map for context and file dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Molinaro committed Nov 14, 2021
1 parent d96f23e commit 0ae8c6d
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 80 deletions.
6 changes: 0 additions & 6 deletions lib/Compilation.js
Expand Up @@ -885,12 +885,6 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
if (compiler.fileTimestamps) {
this.fileSystemInfo.addFileTimestamps(compiler.fileTimestamps, true);
}
if (compiler.contextTimestamps) {
this.fileSystemInfo.addContextTimestamps(
compiler.contextTimestamps,
true
);
}
/** @type {Map<string, string | Set<string>>} */
this.valueCacheVersions = new Map();
this.requestShortener = compiler.requestShortener;
Expand Down
32 changes: 15 additions & 17 deletions lib/FileSystemInfo.js
Expand Up @@ -951,7 +951,7 @@ class FileSystemInfo {
/** @type {Map<string, TimestampAndHash | string>} */
this._fileTshs = new Map();
/** @type {StackedCacheMap<string, ContextFileSystemInfoEntry | "ignore" | null>} */
this._contextTimestamps = new StackedCacheMap();
this._contextTimestamps = this._fileTimestamps;
/** @type {Map<string, ContextHash>} */
this._contextHashes = new Map();
/** @type {Map<string, ContextTimestampAndHash>} */
Expand Down Expand Up @@ -1016,8 +1016,7 @@ class FileSystemInfo {
this.immutablePaths.filter(p => typeof p !== "string")
);

this._cachedDeprecatedFileTimestamps = undefined;
this._cachedDeprecatedContextTimestamps = undefined;
this._cachedDeprecatedTimestamps = undefined;

this._warnAboutExperimentalEsmTracking = false;

Expand Down Expand Up @@ -1152,8 +1151,7 @@ class FileSystemInfo {
this._managedItems.clear();
this._managedItems.clear();

this._cachedDeprecatedFileTimestamps = undefined;
this._cachedDeprecatedContextTimestamps = undefined;
this._cachedDeprecatedTimestamps = undefined;

this._statCreatedSnapshots = 0;
this._statTestedSnapshotsCached = 0;
Expand All @@ -1170,7 +1168,7 @@ class FileSystemInfo {
*/
addFileTimestamps(map, immutable) {
this._fileTimestamps.addAll(map, immutable);
this._cachedDeprecatedFileTimestamps = undefined;
this._cachedDeprecatedTimestamps = undefined;
}

/**
Expand All @@ -1180,7 +1178,7 @@ class FileSystemInfo {
*/
addContextTimestamps(map, immutable) {
this._contextTimestamps.addAll(map, immutable);
this._cachedDeprecatedContextTimestamps = undefined;
this._cachedDeprecatedTimestamps = undefined;
}

/**
Expand Down Expand Up @@ -2804,7 +2802,7 @@ class FileSystemInfo {
if (err) {
if (err.code === "ENOENT") {
this._fileTimestamps.set(path, null);
this._cachedDeprecatedFileTimestamps = undefined;
this._cachedDeprecatedTimestamps = undefined;
return callback(null, null);
}
return callback(err);
Expand All @@ -2828,7 +2826,7 @@ class FileSystemInfo {
}

this._fileTimestamps.set(path, ts);
this._cachedDeprecatedFileTimestamps = undefined;
this._cachedDeprecatedTimestamps = undefined;

callback(null, ts);
});
Expand Down Expand Up @@ -3042,7 +3040,7 @@ class FileSystemInfo {
};

this._fileTimestamps.set(file, ts);
this._cachedDeprecatedFileTimestamps = undefined;
this._cachedDeprecatedTimestamps = undefined;
callback(null, ts);
},
fromDirectory: (directory, stat, callback) => {
Expand Down Expand Up @@ -3093,7 +3091,7 @@ class FileSystemInfo {
(err, result) => {
if (err) return callback(err);
this._contextTimestamps.set(path, result);
this._cachedDeprecatedContextTimestamps = undefined;
this._cachedDeprecatedTimestamps = undefined;

callback(null, result);
}
Expand Down Expand Up @@ -3499,23 +3497,23 @@ class FileSystemInfo {
}

getDeprecatedFileTimestamps() {
if (this._cachedDeprecatedFileTimestamps !== undefined)
return this._cachedDeprecatedFileTimestamps;
if (this._cachedDeprecatedTimestamps !== undefined)
return this._cachedDeprecatedTimestamps;
const map = new Map();
for (const [path, info] of this._fileTimestamps) {
if (info) map.set(path, typeof info === "object" ? info.safeTime : null);
}
return (this._cachedDeprecatedFileTimestamps = map);
return (this._cachedDeprecatedTimestamps = map);
}

getDeprecatedContextTimestamps() {
if (this._cachedDeprecatedContextTimestamps !== undefined)
return this._cachedDeprecatedContextTimestamps;
if (this._cachedDeprecatedTimestamps !== undefined)
return this._cachedDeprecatedTimestamps;
const map = new Map();
for (const [path, info] of this._contextTimestamps) {
if (info) map.set(path, typeof info === "object" ? info.safeTime : null);
}
return (this._cachedDeprecatedContextTimestamps = map);
return (this._cachedDeprecatedTimestamps = map);
}
}

Expand Down
39 changes: 16 additions & 23 deletions lib/WatchIgnorePlugin.js
Expand Up @@ -50,44 +50,37 @@ class IgnoringWatchFileSystem {
missing,
startTime,
options,
(err, fileTimestamps, dirTimestamps, changedFiles, removedFiles) => {
(err, fileTimestamps, changedFiles, removedFiles) => {
if (err) return callback(err);
for (const path of ignoredFiles) {
fileTimestamps.set(path, IGNORE_TIME_ENTRY);
}

for (const path of ignoredDirs) {
dirTimestamps.set(path, IGNORE_TIME_ENTRY);
fileTimestamps.set(path, IGNORE_TIME_ENTRY);
}

callback(
err,
fileTimestamps,
dirTimestamps,
changedFiles,
removedFiles
);
callback(err, fileTimestamps, changedFiles, removedFiles);
},
callbackUndelayed
);

const getTimeInfoEntries = () => {
const fileTimestamps = watcher.getFileTimeInfoEntries();
for (const path of ignoredFiles) {
fileTimestamps.set(path, IGNORE_TIME_ENTRY);
}
for (const path of ignoredDirs) {
fileTimestamps.set(path, IGNORE_TIME_ENTRY);
}
return fileTimestamps;
};

return {
close: () => watcher.close(),
pause: () => watcher.pause(),
getContextTimeInfoEntries: () => {
const dirTimestamps = watcher.getContextTimeInfoEntries();
for (const path of ignoredDirs) {
dirTimestamps.set(path, IGNORE_TIME_ENTRY);
}
return dirTimestamps;
},
getFileTimeInfoEntries: () => {
const fileTimestamps = watcher.getFileTimeInfoEntries();
for (const path of ignoredFiles) {
fileTimestamps.set(path, IGNORE_TIME_ENTRY);
}
return fileTimestamps;
}
getFileTimeInfoEntries: getTimeInfoEntries,
getContextTimeInfoEntries: getTimeInfoEntries
};
}
}
Expand Down
37 changes: 6 additions & 31 deletions lib/Watching.js
Expand Up @@ -91,12 +91,11 @@ class Watching {

/**
* @param {ReadonlyMap<string, FileSystemInfoEntry | "ignore">=} fileTimeInfoEntries info for files
* @param {ReadonlyMap<string, FileSystemInfoEntry | "ignore">=} contextTimeInfoEntries info for directories
* @param {ReadonlySet<string>=} changedFiles changed files
* @param {ReadonlySet<string>=} removedFiles removed files
* @returns {void}
*/
_go(fileTimeInfoEntries, contextTimeInfoEntries, changedFiles, removedFiles) {
_go(fileTimeInfoEntries, changedFiles, removedFiles) {
this._initial = false;
if (this.startTime === null) this.startTime = Date.now();
this.running = true;
Expand Down Expand Up @@ -126,12 +125,9 @@ class Watching {
this.compiler.removedFiles = this._collectedRemovedFiles;
this._collectedRemovedFiles = undefined;

this.compiler.fileTimestamps =
this.compiler.fileTimestamps = this.compiler.contextTimestamps =
fileTimeInfoEntries ||
(this.pausedWatcher && this.pausedWatcher.getFileTimeInfoEntries());
this.compiler.contextTimestamps =
contextTimeInfoEntries ||
(this.pausedWatcher && this.pausedWatcher.getContextTimeInfoEntries());

const run = () => {
if (this.compiler.idle) {
Expand Down Expand Up @@ -314,13 +310,7 @@ class Watching {
missing,
this.lastWatcherStartTime,
this.watchOptions,
(
err,
fileTimeInfoEntries,
contextTimeInfoEntries,
changedFiles,
removedFiles
) => {
(err, fileTimeInfoEntries, changedFiles, removedFiles) => {
if (err) {
this.compiler.modifiedFiles = undefined;
this.compiler.removedFiles = undefined;
Expand All @@ -329,12 +319,7 @@ class Watching {
this.compiler.fsStartTime = undefined;
return this.handler(err);
}
this._invalidate(
fileTimeInfoEntries,
contextTimeInfoEntries,
changedFiles,
removedFiles
);
this._invalidate(fileTimeInfoEntries, changedFiles, removedFiles);
this._onChange();
},
(fileName, changeTime) => {
Expand Down Expand Up @@ -363,12 +348,7 @@ class Watching {
this._invalidate();
}

_invalidate(
fileTimeInfoEntries,
contextTimeInfoEntries,
changedFiles,
removedFiles
) {
_invalidate(fileTimeInfoEntries, changedFiles, removedFiles) {
if (this.suspended || (this._isBlocked() && (this.blocked = true))) {
this._mergeWithCollected(changedFiles, removedFiles);
return;
Expand All @@ -378,12 +358,7 @@ class Watching {
this._mergeWithCollected(changedFiles, removedFiles);
this.invalid = true;
} else {
this._go(
fileTimeInfoEntries,
contextTimeInfoEntries,
changedFiles,
removedFiles
);
this._go(fileTimeInfoEntries, changedFiles, removedFiles);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/node/NodeWatchFileSystem.js
Expand Up @@ -79,7 +79,7 @@ class NodeWatchFileSystem {
}
}
const times = this.watcher.getTimeInfoEntries();
callback(null, times, times, changes, removals);
callback(null, times, changes, removals);
});

this.watcher.watch({ files, directories, missing, startTime });
Expand Down
2 changes: 1 addition & 1 deletion lib/util/fs.js
Expand Up @@ -68,7 +68,7 @@ const path = require("path");
* @property {function(): Set<string>=} getAggregatedChanges get current aggregated changes that have not yet send to callback
* @property {function(): Set<string>=} getAggregatedRemovals get current aggregated removals that have not yet send to callback
* @property {function(): Map<string, FileSystemInfoEntry | "ignore">} getFileTimeInfoEntries get info about files
* @property {function(): Map<string, FileSystemInfoEntry | "ignore">} getContextTimeInfoEntries get info about directories
* @property {function(): Map<string, FileSystemInfoEntry | "ignore">} getContextTimeInfoEntries deprecated - use getFileTimeInfoEntries instead (TODO remove in webpack 6).
*/

/**
Expand Down
3 changes: 2 additions & 1 deletion types.d.ts
Expand Up @@ -6260,6 +6260,7 @@ declare interface LoaderRunnerLoaderContext<OptionsType> {
/**
* An array of all the loaders. It is writeable in the pitch phase.
* loaders = [{request: string, path: string, query: string, module: function}]
*
* In the example:
* [
* { request: "/abc/loader1.js?xyz",
Expand Down Expand Up @@ -11734,7 +11735,7 @@ declare interface Watcher {
getFileTimeInfoEntries: () => Map<string, FileSystemInfoEntry | "ignore">;

/**
* get info about directories
* deprecated - use getFileTimeInfoEntries instead (TODO remove in webpack 6).
*/
getContextTimeInfoEntries: () => Map<string, FileSystemInfoEntry | "ignore">;
}
Expand Down

0 comments on commit 0ae8c6d

Please sign in to comment.