Skip to content

Commit 22ef17a

Browse files
committed
perf(fslib): reduce fs calls in findZip
1 parent 206b955 commit 22ef17a

File tree

3 files changed

+39
-79
lines changed

3 files changed

+39
-79
lines changed

.pnp.js

Lines changed: 18 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/yarnpkg-fslib/sources/ZipOpenFS.ts

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {Filename, FSPath, PortablePath}
1111

1212
const ZIP_FD = 0x80000000;
1313

14+
const FILE_PARTS_REGEX = /.*?(?<!\/|\\)\.zip(?=\/|\\|$)/;
15+
1416
export type ZipOpenFSOptions = {
1517
baseFs?: FakeFS<PortablePath>,
1618
filter?: RegExp | null,
@@ -59,9 +61,6 @@ export class ZipOpenFS extends BasePortableFakeFS {
5961
this.filter = filter;
6062
this.maxOpenFiles = maxOpenFiles;
6163
this.readOnlyArchives = readOnlyArchives;
62-
63-
this.isZip = new Set();
64-
this.notZip = new Set();
6564
}
6665

6766
getExtractHint(hints: ExtractHintOptions) {
@@ -687,51 +686,34 @@ export class ZipOpenFS extends BasePortableFakeFS {
687686
}
688687

689688
private findZip(p: PortablePath) {
690-
if (this.filter && !this.filter.test(p))
691-
return null;
692-
693-
const parts = p.split(/\//g);
689+
if (this.filter && !this.filter.test(p)) return null;
694690

695-
for (let t = 2; t <= parts.length; ++t) {
696-
const archivePath = parts.slice(0, t).join(`/`) as PortablePath;
691+
let filePath = `` as PortablePath;
697692

698-
if (this.notZip.has(archivePath))
699-
continue;
693+
while (true) {
694+
const parts = FILE_PARTS_REGEX.exec(p.substr(filePath.length));
695+
if (!parts)
696+
return null;
700697

701-
if (this.isZip.has(archivePath))
702-
return {archivePath, subPath: this.pathUtils.resolve(PortablePath.root, parts.slice(t).join(`/`) as PortablePath)};
698+
filePath = this.pathUtils.join(filePath, parts[0] as PortablePath);
703699

704-
let realArchivePath = archivePath;
705-
let stat;
700+
if (this.isZip.has(filePath) === false) {
701+
if (this.notZip.has(filePath))
702+
continue;
706703

707-
while (true) {
708-
try {
709-
stat = this.baseFs.lstatSync(realArchivePath);
710-
} catch (error) {
711-
return null;
704+
if (this.baseFs.lstatSync(filePath).isFile() === false) {
705+
this.notZip.add(filePath);
706+
continue;
712707
}
713708

714-
if (stat.isSymbolicLink()) {
715-
realArchivePath = this.pathUtils.resolve(this.pathUtils.dirname(realArchivePath), this.baseFs.readlinkSync(realArchivePath));
716-
} else {
717-
break;
718-
}
709+
this.isZip.add(filePath);
719710
}
720711

721-
const isZip = stat.isFile() && this.pathUtils.extname(realArchivePath) === `.zip`;
722-
723-
if (isZip) {
724-
this.isZip.add(archivePath);
725-
return {archivePath, subPath: this.pathUtils.resolve(PortablePath.root, parts.slice(t).join(`/`) as PortablePath)};
726-
} else {
727-
this.notZip.add(archivePath);
728-
if (stat.isFile()) {
729-
return null;
730-
}
731-
}
712+
return {
713+
archivePath: filePath,
714+
subPath: this.pathUtils.resolve(PortablePath.root, p.substr(filePath.length) as PortablePath),
715+
};
732716
}
733-
734-
return null;
735717
}
736718

737719
private limitOpenFiles(max: number) {

packages/yarnpkg-pnp/sources/hook.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)