Skip to content

Commit

Permalink
perf(fslib): reduce fs calls in findZip
Browse files Browse the repository at this point in the history
  • Loading branch information
merceyz committed Jun 15, 2020
1 parent 206b955 commit 22ef17a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 79 deletions.
58 changes: 18 additions & 40 deletions .pnp.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 20 additions & 38 deletions packages/yarnpkg-fslib/sources/ZipOpenFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {Filename, FSPath, PortablePath}

const ZIP_FD = 0x80000000;

const FILE_PARTS_REGEX = /.*?(?<!\/|\\)\.zip(?=\/|\\|$)/;

export type ZipOpenFSOptions = {
baseFs?: FakeFS<PortablePath>,
filter?: RegExp | null,
Expand Down Expand Up @@ -59,9 +61,6 @@ export class ZipOpenFS extends BasePortableFakeFS {
this.filter = filter;
this.maxOpenFiles = maxOpenFiles;
this.readOnlyArchives = readOnlyArchives;

this.isZip = new Set();
this.notZip = new Set();
}

getExtractHint(hints: ExtractHintOptions) {
Expand Down Expand Up @@ -687,51 +686,34 @@ export class ZipOpenFS extends BasePortableFakeFS {
}

private findZip(p: PortablePath) {
if (this.filter && !this.filter.test(p))
return null;

const parts = p.split(/\//g);
if (this.filter && !this.filter.test(p)) return null;

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

if (this.notZip.has(archivePath))
continue;
while (true) {
const parts = FILE_PARTS_REGEX.exec(p.substr(filePath.length));
if (!parts)
return null;

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

let realArchivePath = archivePath;
let stat;
if (this.isZip.has(filePath) === false) {
if (this.notZip.has(filePath))
continue;

while (true) {
try {
stat = this.baseFs.lstatSync(realArchivePath);
} catch (error) {
return null;
if (this.baseFs.lstatSync(filePath).isFile() === false) {
this.notZip.add(filePath);
continue;
}

if (stat.isSymbolicLink()) {
realArchivePath = this.pathUtils.resolve(this.pathUtils.dirname(realArchivePath), this.baseFs.readlinkSync(realArchivePath));
} else {
break;
}
this.isZip.add(filePath);
}

const isZip = stat.isFile() && this.pathUtils.extname(realArchivePath) === `.zip`;

if (isZip) {
this.isZip.add(archivePath);
return {archivePath, subPath: this.pathUtils.resolve(PortablePath.root, parts.slice(t).join(`/`) as PortablePath)};
} else {
this.notZip.add(archivePath);
if (stat.isFile()) {
return null;
}
}
return {
archivePath: filePath,
subPath: this.pathUtils.resolve(PortablePath.root, p.substr(filePath.length) as PortablePath),
};
}

return null;
}

private limitOpenFiles(max: number) {
Expand Down
2 changes: 1 addition & 1 deletion packages/yarnpkg-pnp/sources/hook.js

Large diffs are not rendered by default.

0 comments on commit 22ef17a

Please sign in to comment.