Skip to content

Commit 95b8f5d

Browse files
authored
stream: optimize Writable
PR-URL: #50012 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]>
1 parent 55ff640 commit 95b8f5d

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

lib/internal/streams/writable.js

+22-10
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ const kWriteCb = 1 << 26;
108108
const kExpectWriteCb = 1 << 27;
109109
const kAfterWriteTickInfo = 1 << 28;
110110
const kAfterWritePending = 1 << 29;
111+
const kHasBuffer = 1 << 30;
111112

112113
// TODO(benjamingr) it is likely slower to do it this way than with free functions
113114
function makeBitMapDescriptor(bit) {
@@ -340,6 +341,7 @@ function resetBuffer(state) {
340341
state.buffered = [];
341342
state.bufferedIndex = 0;
342343
state.state |= kAllBuffers | kAllNoop;
344+
state.state &= ~kHasBuffer;
343345
}
344346

345347
WritableState.prototype.getBuffer = function getBuffer() {
@@ -396,11 +398,13 @@ function Writable(options) {
396398
destroyImpl.construct(this, () => {
397399
const state = this._writableState;
398400

399-
if (!state.writing) {
401+
if ((state.state & kWriting) === 0) {
400402
clearBuffer(this, state);
401403
}
402404

403-
finishMaybe(this, state);
405+
if ((state.state & kEnding) !== 0) {
406+
finishMaybe(this, state);
407+
}
404408
});
405409
}
406410

@@ -523,6 +527,7 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) {
523527

524528
if ((state.state & (kWriting | kErrored | kCorked | kConstructed)) !== kConstructed) {
525529
state.buffered.push({ chunk, encoding, callback });
530+
state.state |= kHasBuffer;
526531
if ((state.state & kAllBuffers) !== 0 && encoding !== 'buffer') {
527532
state.state &= ~kAllBuffers;
528533
}
@@ -591,8 +596,9 @@ function onwrite(stream, er) {
591596
// Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364
592597
er.stack; // eslint-disable-line no-unused-expressions
593598

594-
if (!state.errored) {
595-
state.errored = er;
599+
if ((state.state & kErrored) === 0) {
600+
state[kErroredValue] = er;
601+
state.state |= kErrored;
596602
}
597603

598604
// In case of duplex streams we need to notify the readable side of the
@@ -607,12 +613,12 @@ function onwrite(stream, er) {
607613
onwriteError(stream, state, er, cb);
608614
}
609615
} else {
610-
if (state.buffered.length > state.bufferedIndex) {
616+
if ((state.state & kHasBuffer) !== 0) {
611617
clearBuffer(stream, state);
612618
}
613619

614620
if (sync) {
615-
const needDrain = state.length === 0 && (state.state & kNeedDrain) !== 0;
621+
const needDrain = (state.state & kNeedDrain) !== 0 && state.length === 0;
616622
const needTick = needDrain || (state.state & kDestroyed !== 0) || cb !== nop;
617623

618624
// It is a common case that the callback passed to .write() is always
@@ -625,7 +631,9 @@ function onwrite(stream, er) {
625631
state.state |= kAfterWritePending;
626632
} else {
627633
state.pendingcb--;
628-
finishMaybe(stream, state, true);
634+
if ((state.state & kEnding) !== 0) {
635+
finishMaybe(stream, state, true);
636+
}
629637
}
630638
} else if ((state.state & kAfterWriteTickInfo) !== 0 &&
631639
state[kAfterWriteTickInfoValue].cb === cb) {
@@ -636,7 +644,9 @@ function onwrite(stream, er) {
636644
state.state |= (kAfterWritePending | kAfterWriteTickInfo);
637645
} else {
638646
state.pendingcb--;
639-
finishMaybe(stream, state, true);
647+
if ((state.state & kEnding) !== 0) {
648+
finishMaybe(stream, state, true);
649+
}
640650
}
641651
} else {
642652
afterWrite(stream, state, 1, cb);
@@ -668,7 +678,9 @@ function afterWrite(stream, state, count, cb) {
668678
errorBuffer(state);
669679
}
670680

671-
finishMaybe(stream, state);
681+
if ((state.state & kEnding) !== 0) {
682+
finishMaybe(stream, state, true);
683+
}
672684
}
673685

674686
// If there's something in the buffer waiting, then invoke callbacks.
@@ -692,7 +704,7 @@ function errorBuffer(state) {
692704

693705
// If there's something in the buffer waiting, then process it.
694706
function clearBuffer(stream, state) {
695-
if ((state.state & (kDestroyed | kBufferProcessing | kCorked)) !== 0 ||
707+
if ((state.state & (kDestroyed | kBufferProcessing | kCorked | kHasBuffer)) !== kHasBuffer ||
696708
(state.state & kConstructed) === 0) {
697709
return;
698710
}

0 commit comments

Comments
 (0)