fs: make stats date fields lazy

PR-URL: https://github.com/nodejs/node/pull/50908
Reviewed-By: Raz Luvaton <rluvaton@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
Yagiz Nizipli
2023-12-20 20:20:33 -05:00
committed by GitHub
parent 7afaf463d4
commit abbdc3efaa
2 changed files with 60 additions and 14 deletions

View File

@@ -12,6 +12,8 @@ const {
NumberIsFinite,
MathMin,
MathRound,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectIs,
ObjectSetPrototypeOf,
ReflectApply,
@@ -449,6 +451,62 @@ function dateFromMs(ms) {
return new Date(MathRound(Number(ms)));
}
const lazyDateFields = {
__proto__: null,
atime: {
__proto__: null,
enumerable: true,
configurable: true,
get() {
const value = dateFromMs(this.atimeMs);
ObjectDefineProperty(this, 'atime', { __proto__: null, value });
return this.atime;
},
set(value) {
this.atime = value;
},
},
mtime: {
__proto__: null,
enumerable: true,
configurable: true,
get() {
const value = dateFromMs(this.mtimeMs);
ObjectDefineProperty(this, 'mtime', { __proto__: null, value });
return this.mtime;
},
set(value) {
this.mtime = value;
},
},
ctime: {
__proto__: null,
enumerable: true,
configurable: true,
get() {
const value = dateFromMs(this.ctimeMs);
ObjectDefineProperty(this, 'ctime', { __proto__: null, value });
return this.ctime;
},
set(value) {
this.ctime = value;
},
},
birthtime: {
__proto__: null,
enumerable: true,
configurable: true,
get() {
const value = dateFromMs(this.birthtimeMs);
ObjectDefineProperty(this, 'birthtime', { __proto__: null, value });
return this.birthtime;
},
set(value) {
this.birthtime = value;
},
},
};
function BigIntStats(dev, mode, nlink, uid, gid, rdev, blksize,
ino, size, blocks,
atimeNs, mtimeNs, ctimeNs, birthtimeNs) {
@@ -463,14 +521,11 @@ function BigIntStats(dev, mode, nlink, uid, gid, rdev, blksize,
this.mtimeNs = mtimeNs;
this.ctimeNs = ctimeNs;
this.birthtimeNs = birthtimeNs;
this.atime = dateFromMs(this.atimeMs);
this.mtime = dateFromMs(this.mtimeMs);
this.ctime = dateFromMs(this.ctimeMs);
this.birthtime = dateFromMs(this.birthtimeMs);
}
ObjectSetPrototypeOf(BigIntStats.prototype, StatsBase.prototype);
ObjectSetPrototypeOf(BigIntStats, StatsBase);
ObjectDefineProperties(BigIntStats.prototype, lazyDateFields);
BigIntStats.prototype._checkModeProperty = function(property) {
if (isWindows && (property === S_IFIFO || property === S_IFBLK ||
@@ -489,14 +544,11 @@ function Stats(dev, mode, nlink, uid, gid, rdev, blksize,
this.mtimeMs = mtimeMs;
this.ctimeMs = ctimeMs;
this.birthtimeMs = birthtimeMs;
this.atime = dateFromMs(atimeMs);
this.mtime = dateFromMs(mtimeMs);
this.ctime = dateFromMs(ctimeMs);
this.birthtime = dateFromMs(birthtimeMs);
}
ObjectSetPrototypeOf(Stats.prototype, StatsBase.prototype);
ObjectSetPrototypeOf(Stats, StatsBase);
ObjectDefineProperties(Stats.prototype, lazyDateFields);
Stats.prototype._checkModeProperty = function(property) {
if (isWindows && (property === S_IFIFO || property === S_IFBLK ||

View File

@@ -80,8 +80,6 @@ fs.stat(__filename, common.mustSucceed((s) => {
assert.strictEqual(s.isFIFO(), false);
assert.strictEqual(s.isSymbolicLink(), false);
const jsonString = JSON.stringify(s);
const parsed = JSON.parse(jsonString);
[
'dev', 'mode', 'nlink', 'uid',
'gid', 'rdev', 'blksize', 'ino', 'size', 'blocks',
@@ -91,19 +89,15 @@ fs.stat(__filename, common.mustSucceed((s) => {
assert.ok(k in s, `${k} should be in Stats`);
assert.notStrictEqual(s[k], undefined, `${k} should not be undefined`);
assert.notStrictEqual(s[k], null, `${k} should not be null`);
assert.notStrictEqual(parsed[k], undefined, `${k} should not be undefined`);
assert.notStrictEqual(parsed[k], null, `${k} should not be null`);
});
[
'dev', 'mode', 'nlink', 'uid', 'gid', 'rdev', 'blksize', 'ino', 'size',
'blocks', 'atimeMs', 'mtimeMs', 'ctimeMs', 'birthtimeMs',
].forEach((k) => {
assert.strictEqual(typeof s[k], 'number', `${k} should be a number`);
assert.strictEqual(typeof parsed[k], 'number', `${k} should be a number`);
});
['atime', 'mtime', 'ctime', 'birthtime'].forEach((k) => {
assert.ok(s[k] instanceof Date, `${k} should be a Date`);
assert.strictEqual(typeof parsed[k], 'string', `${k} should be a string`);
});
}));