Skip to content

Commit

Permalink
lib: lazy instantiation of fs.Stats dates
Browse files Browse the repository at this point in the history
The method used has code duplication but is the most performant

PR-URL: #12818
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
  • Loading branch information
sciolist authored and jasnell committed May 23, 2017
1 parent d326a7b commit c0fedf7
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 4 deletions.
74 changes: 70 additions & 4 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,79 @@ function Stats(
this.ino = ino;
this.size = size;
this.blocks = blocks;
this.atime = new Date(atim_msec);
this.mtime = new Date(mtim_msec);
this.ctime = new Date(ctim_msec);
this.birthtime = new Date(birthtim_msec);
this._atim_msec = atim_msec;
this._mtim_msec = mtim_msec;
this._ctim_msec = ctim_msec;
this._birthtim_msec = birthtim_msec;
}
fs.Stats = Stats;

// defining the properties in this fashion (explicitly with no loop or factory)
// has been shown to be the most performant on V8 contemp.
// Ref: https://github.com/nodejs/node/pull/12818
Object.defineProperties(Stats.prototype, {
atime: {
configurable: true,
enumerable: true,
get() {
return this._atime !== undefined ?
this._atime :
(this._atime = new Date(this._atim_msec + 0.5));
},
set(value) { return this._atime = value; }
},
mtime: {
configurable: true,
enumerable: true,
get() {
return this._mtime !== undefined ?
this._mtime :
(this._mtime = new Date(this._mtim_msec + 0.5));
},
set(value) { return this._mtime = value; }
},
ctime: {
configurable: true,
enumerable: true,
get() {
return this._ctime !== undefined ?
this._ctime :
(this._ctime = new Date(this._ctim_msec + 0.5));
},
set(value) { return this._ctime = value; }
},
birthtime: {
configurable: true,
enumerable: true,
get() {
return this._birthtime !== undefined ?
this._birthtime :
(this._birthtime = new Date(this._birthtim_msec + 0.5));
},
set(value) { return this._birthtime = value; }
},
});

Stats.prototype.toJSON = function toJSON() {
return {
dev: this.dev,
mode: this.mode,
nlink: this.nlink,
uid: this.uid,
gid: this.gid,
rdev: this.rdev,
blksize: this.blksize,
ino: this.ino,
size: this.size,
blocks: this.blocks,
atime: this.atime,
ctime: this.ctime,
mtime: this.mtime,
birthtime: this.birthtime
};
};


Stats.prototype._checkModeProperty = function(property) {
return ((this.mode & S_IFMT) === property);
};
Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-fs-stat.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,27 @@ fs.stat(__filename, common.mustCall(function(err, s) {
console.log(`isSymbolicLink: ${JSON.stringify(s.isSymbolicLink())}`);
assert.strictEqual(false, s.isSymbolicLink());

assert.ok(s.atime instanceof Date);
assert.ok(s.mtime instanceof Date);
assert.ok(s.ctime instanceof Date);
assert.ok(s.birthtime instanceof Date);
}));

fs.stat(__filename, common.mustCall(function(err, s) {
const json = JSON.parse(JSON.stringify(s));
const keys = [
'dev', 'mode', 'nlink', 'uid',
'gid', 'rdev', 'ino',
'size', 'atime', 'mtime',
'ctime', 'birthtime'
];
if (!common.isWindows) {
keys.push('blocks', 'blksize');
}
keys.forEach(function(k) {
assert.ok(
json[k] !== undefined && json[k] !== null,
k + ' should not be null or undefined'
);
});
}));

0 comments on commit c0fedf7

Please sign in to comment.