-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
Lazy stat dates #12818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lazy stat dates #12818
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -196,13 +196,76 @@ function Stats( | |
| this.ino = ino; | ||
| this.size = size; | ||
| this.blocks = blocks; | ||
| this.atime = new Date(atim_msec + 0.5); | ||
| this.mtime = new Date(mtim_msec + 0.5); | ||
| this.ctime = new Date(ctim_msec + 0.5); | ||
| this.birthtime = new Date(birthtim_msec + 0.5); | ||
| this._atim_msec = atim_msec; | ||
| this._mtim_msec = mtim_msec; | ||
| this._ctim_msec = ctim_msec; | ||
| this._birthtim_msec = birthtim_msec; | ||
| } | ||
| fs.Stats = Stats; | ||
|
|
||
| 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)); | ||
| }, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can eliminate some code duplication here by having a factory function for the getters... e.g. function makeGetter(name, src) {
return function() {
return this[name] !== undefined ?
this[name] : (this[name] = new Date(this[src + 0.5));
};
}
// ...
Object.defineProperties(Stats.prototype, {
atime: {
configurable: true,
enumerable: true,
get: makeGetter('_atime', '_atim_msec'),
// etc
}
});
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another idea here would be to use another defineProperty within the getter to replace the value once the date is created... var m = {};
Object.defineProperty(m, 'a', {
configurable: true,
enumerable: true,
get() {
const val = 1;
delete this.a;
Object.defineProperty(this, 'a', { configurable: true, enumerable: true, value: val } );
return val;
}
});The getter is called once, during which time it is deleted, and the static value is set... and will be returned every time after. Should have a slightly better performance profile.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @TimothyGu suggested that in the previous PR, it wasn't performant enough for the "single access" case - #12607 (comment)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, that's fine then. I'd still suggest the factory function to avoid the code duplication
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey, yeah I have tried these variations. Unfortunately a single
|
||
| 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); | ||
| }; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -98,5 +98,21 @@ 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 = [ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On second thought: either put a comment saying why we exclude
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just found out need to do the same for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i added an |
||
| 'dev', 'mode', 'nlink', 'uid', | ||
| 'gid', 'rdev', 'blksize', 'ino', | ||
| 'size', 'blocks', 'atime', 'mtime', | ||
| 'ctime', 'birthtime' | ||
| ]; | ||
| keys.forEach(function(k) { | ||
| assert.ok(json[k] !== undefined && json[k] !== null); | ||
| }); | ||
| })); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might as well make these public? ¯\_(ツ)_/¯ If not, I agree that using Symbols may be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer the Symbol approach for these.