Optimise some special cases in StreamReader; return a new Buffer from read() immediately if there's enough buffered data, and if the read can be fulfilled entirely from the first queued buffer than take a slice rather than copying into a new buffer.

This commit is contained in:
James Coglan
2014-05-11 13:33:51 +01:00
parent 85ba40ac32
commit bf39b7b44b
+21 -4
View File
@@ -57,6 +57,9 @@ StreamReader.prototype.fork = function(length) {
StreamReader.prototype.read = function(length, callback) {
if (!this.writable) return;
if (this._queueSize >= length)
return callback.call(this._context, this._readBytes(length));
var self = this;
this.fork(length).pipe(new Concat(function(buffer) {
@@ -67,7 +70,7 @@ StreamReader.prototype.read = function(length, callback) {
StreamReader.prototype._flush = function() {
var streams = this._streams, stream, size, buffer;
while (streams.length > 0 && this._queueSize >= 0) {
while (streams.length > 0 && this._queueSize > 0) {
stream = streams[0];
size = Math.min(stream._remaining, this._queueSize);
buffer = this._readBytes(size);
@@ -84,12 +87,26 @@ StreamReader.prototype._flush = function() {
};
StreamReader.prototype._readBytes = function(length) {
var buffer = new Buffer(length),
queue = this._queue,
var queue = this._queue,
remain = length,
n = queue.length,
first = queue[0],
i = 0,
chunk, size;
buffer, chunk, size;
if (length === 0) return new Buffer(0);
if (remain <= first.length - this._cursor) {
buffer = first.slice(this._cursor, this._cursor + remain);
this._queueSize -= remain;
this._cursor = (this._cursor + remain) % first.length;
if (this._cursor === 0) this._queue.shift();
return buffer;
}
buffer = new Buffer(length);
while (remain > 0 && i < n) {
chunk = queue[i];