Skip to content
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

stream: optimize creation #29135

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions lib/_stream_readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ const { Buffer } = require('buffer');
const debug = require('internal/util/debuglog').debuglog('stream');
const BufferList = require('internal/streams/buffer_list');
const destroyImpl = require('internal/streams/destroy');
const { getHighWaterMark } = require('internal/streams/state');
const {
getHighWaterMark,
getDefaultHighWaterMark
} = require('internal/streams/state');
const {
ERR_INVALID_ARG_TYPE,
ERR_STREAM_PUSH_AFTER_EOF,
Expand Down Expand Up @@ -70,8 +73,6 @@ function prependListener(emitter, event, fn) {
}

function ReadableState(options, stream, isDuplex) {
options = options || {};

// Duplex streams are both readable and writable, but share
// the same options object.
// However, some cases require setting options to different
Expand All @@ -82,15 +83,17 @@ function ReadableState(options, stream, isDuplex) {

// Object stream flag. Used to make read(n) ignore n and to
// make all the buffer merging and length checks go away
this.objectMode = !!options.objectMode;
this.objectMode = !!(options && options.objectMode);

if (isDuplex)
this.objectMode = this.objectMode || !!options.readableObjectMode;
this.objectMode = this.objectMode ||
!!(options && options.readableObjectMode);

// The point at which it stops calling _read() to fill the buffer
// Note: 0 is a valid value, means "don't call _read preemptively ever"
this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark',
isDuplex);
this.highWaterMark = options ?
getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex) :
getDefaultHighWaterMark(false);

// A linked list is used to store data chunks instead of an array because the
// linked list can remove elements from the beginning faster than
Expand Down Expand Up @@ -121,18 +124,18 @@ function ReadableState(options, stream, isDuplex) {
this.errorEmitted = false;

// Should close be emitted on destroy. Defaults to true.
this.emitClose = options.emitClose !== false;
this.emitClose = !options || options.emitClose !== false;

// Should .destroy() be called after 'end' (and potentially 'finish')
this.autoDestroy = !!options.autoDestroy;
this.autoDestroy = !!(options && options.autoDestroy);

// Has it been destroyed
this.destroyed = false;

// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
this.defaultEncoding = (options && options.defaultEncoding) || 'utf8';

// Ref the piped dest which we need a drain event on it
// type: null | Writable | Set<Writable>
Expand All @@ -144,7 +147,7 @@ function ReadableState(options, stream, isDuplex) {

this.decoder = null;
this.encoding = null;
if (options.encoding) {
if (options && options.encoding) {
if (!StringDecoder)
StringDecoder = require('string_decoder').StringDecoder;
this.decoder = new StringDecoder(options.encoding);
Expand Down
25 changes: 14 additions & 11 deletions lib/_stream_writable.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ const internalUtil = require('internal/util');
const Stream = require('stream');
const { Buffer } = require('buffer');
const destroyImpl = require('internal/streams/destroy');
const { getHighWaterMark } = require('internal/streams/state');
const {
getHighWaterMark,
getDefaultHighWaterMark
} = require('internal/streams/state');
const {
ERR_INVALID_ARG_TYPE,
ERR_METHOD_NOT_IMPLEMENTED,
Expand All @@ -55,8 +58,6 @@ Object.setPrototypeOf(Writable, Stream);
function nop() {}

function WritableState(options, stream, isDuplex) {
options = options || {};

// Duplex streams are both readable and writable, but share
// the same options object.
// However, some cases require setting options to different
Expand All @@ -67,16 +68,18 @@ function WritableState(options, stream, isDuplex) {

// Object stream flag to indicate whether or not this stream
// contains buffers or objects.
this.objectMode = !!options.objectMode;
this.objectMode = !!(options && options.objectMode);

if (isDuplex)
this.objectMode = this.objectMode || !!options.writableObjectMode;
this.objectMode = this.objectMode ||
!!(options && options.writableObjectMode);

// The point at which write() starts returning false
// Note: 0 is a valid value, means that we always return false if
// the entire buffer is not flushed immediately on write()
this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark',
isDuplex);
this.highWaterMark = options ?
getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex) :
getDefaultHighWaterMark(false);

// if _final has been called
this.finalCalled = false;
Expand All @@ -96,13 +99,13 @@ function WritableState(options, stream, isDuplex) {
// Should we decode strings into buffers before passing to _write?
// this is here so that some node-core streams can optimize string
// handling at a lower level.
const noDecode = options.decodeStrings === false;
const noDecode = !!(options && options.decodeStrings === false);
this.decodeStrings = !noDecode;

// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
this.defaultEncoding = (options && options.defaultEncoding) || 'utf8';

// Not an actual buffer we keep track of, but a measurement
// of how much we're waiting to get pushed to some underlying
Expand Down Expand Up @@ -150,10 +153,10 @@ function WritableState(options, stream, isDuplex) {
this.errorEmitted = false;

// Should close be emitted on destroy. Defaults to true.
this.emitClose = options.emitClose !== false;
this.emitClose = !options || options.emitClose !== false;

// Should .destroy() be called after 'finish' (and potentially 'end')
this.autoDestroy = !!options.autoDestroy;
this.autoDestroy = !!(options && options.autoDestroy);

// Count buffered requests
this.bufferedRequestCount = 0;
Expand Down