Skip to content

Commit

Permalink
fs: make stats date fields lazy
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Dec 17, 2023
1 parent 0afe731 commit 0e36c55
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 14 deletions.
68 changes: 60 additions & 8 deletions lib/internal/fs/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const {
NumberIsFinite,
MathMin,
MathRound,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectIs,
ObjectSetPrototypeOf,
ReflectApply,
Expand Down Expand Up @@ -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) {
Expand All @@ -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 ||
Expand All @@ -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 ||
Expand Down
6 changes: 0 additions & 6 deletions test/parallel/test-fs-stat.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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`);
});
}));

Expand Down

0 comments on commit 0e36c55

Please sign in to comment.