11cb0ef41Sopenharmony_ci// Test the speed of .pipe() with JSStream wrapping for PassThrough streams
21cb0ef41Sopenharmony_ci'use strict';
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciconst common = require('../common.js');
51cb0ef41Sopenharmony_ciconst { PassThrough } = require('stream');
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst bench = common.createBenchmark(main, {
81cb0ef41Sopenharmony_ci  len: [64, 102400, 1024 * 1024 * 16],
91cb0ef41Sopenharmony_ci  type: ['utf', 'asc', 'buf'],
101cb0ef41Sopenharmony_ci  dur: [5],
111cb0ef41Sopenharmony_ci}, {
121cb0ef41Sopenharmony_ci  test: { len: 64 },
131cb0ef41Sopenharmony_ci  flags: ['--expose-internals'],
141cb0ef41Sopenharmony_ci});
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cilet chunk;
171cb0ef41Sopenharmony_cilet encoding;
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cifunction main({ dur, len, type }) {
201cb0ef41Sopenharmony_ci  // Can only require internals inside main().
211cb0ef41Sopenharmony_ci  const JSStreamWrap = require('internal/js_stream_socket');
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci  switch (type) {
241cb0ef41Sopenharmony_ci    case 'buf':
251cb0ef41Sopenharmony_ci      chunk = Buffer.alloc(len, 'x');
261cb0ef41Sopenharmony_ci      break;
271cb0ef41Sopenharmony_ci    case 'utf':
281cb0ef41Sopenharmony_ci      encoding = 'utf8';
291cb0ef41Sopenharmony_ci      chunk = 'ü'.repeat(len / 2);
301cb0ef41Sopenharmony_ci      break;
311cb0ef41Sopenharmony_ci    case 'asc':
321cb0ef41Sopenharmony_ci      encoding = 'ascii';
331cb0ef41Sopenharmony_ci      chunk = 'x'.repeat(len);
341cb0ef41Sopenharmony_ci      break;
351cb0ef41Sopenharmony_ci    default:
361cb0ef41Sopenharmony_ci      throw new Error(`invalid type: ${type}`);
371cb0ef41Sopenharmony_ci  }
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  const reader = new Reader();
401cb0ef41Sopenharmony_ci  const writer = new Writer();
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  // The actual benchmark.
431cb0ef41Sopenharmony_ci  const fakeSocket = new JSStreamWrap(new PassThrough());
441cb0ef41Sopenharmony_ci  bench.start();
451cb0ef41Sopenharmony_ci  reader.pipe(fakeSocket);
461cb0ef41Sopenharmony_ci  fakeSocket.pipe(writer);
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  setTimeout(() => {
491cb0ef41Sopenharmony_ci    const bytes = writer.received;
501cb0ef41Sopenharmony_ci    const gbits = (bytes * 8) / (1024 * 1024 * 1024);
511cb0ef41Sopenharmony_ci    bench.end(gbits);
521cb0ef41Sopenharmony_ci    process.exit(0);
531cb0ef41Sopenharmony_ci  }, dur * 1000);
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_cifunction Writer() {
571cb0ef41Sopenharmony_ci  this.received = 0;
581cb0ef41Sopenharmony_ci  this.writable = true;
591cb0ef41Sopenharmony_ci}
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ciWriter.prototype.write = function(chunk, encoding, cb) {
621cb0ef41Sopenharmony_ci  this.received += chunk.length;
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  if (typeof encoding === 'function')
651cb0ef41Sopenharmony_ci    encoding();
661cb0ef41Sopenharmony_ci  else if (typeof cb === 'function')
671cb0ef41Sopenharmony_ci    cb();
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  return true;
701cb0ef41Sopenharmony_ci};
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci// Doesn't matter, never emits anything.
731cb0ef41Sopenharmony_ciWriter.prototype.on = function() {};
741cb0ef41Sopenharmony_ciWriter.prototype.once = function() {};
751cb0ef41Sopenharmony_ciWriter.prototype.emit = function() {};
761cb0ef41Sopenharmony_ciWriter.prototype.prependListener = function() {};
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cifunction flow() {
801cb0ef41Sopenharmony_ci  const dest = this.dest;
811cb0ef41Sopenharmony_ci  const res = dest.write(chunk, encoding);
821cb0ef41Sopenharmony_ci  if (!res)
831cb0ef41Sopenharmony_ci    dest.once('drain', this.flow);
841cb0ef41Sopenharmony_ci  else
851cb0ef41Sopenharmony_ci    process.nextTick(this.flow);
861cb0ef41Sopenharmony_ci}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_cifunction Reader() {
891cb0ef41Sopenharmony_ci  this.flow = flow.bind(this);
901cb0ef41Sopenharmony_ci  this.readable = true;
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ciReader.prototype.pipe = function(dest) {
941cb0ef41Sopenharmony_ci  this.dest = dest;
951cb0ef41Sopenharmony_ci  this.flow();
961cb0ef41Sopenharmony_ci  return dest;
971cb0ef41Sopenharmony_ci};
98