Skip to content

Commit

Permalink
On-Demand Dynamic Receive Queue Resizing
Browse files Browse the repository at this point in the history
This commit causes the receive queue to dynamically
resize to fit incoming messages.

Fixes #557
  • Loading branch information
DirectXMan12 committed Dec 22, 2015
1 parent c8f14d1 commit 5bfdd90
Showing 1 changed file with 43 additions and 17 deletions.
60 changes: 43 additions & 17 deletions include/websock.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@ function Websock() {

(function () {
"use strict";

// this has performance issues in some versions Chromium, and
// doesn't gain a tremendous amount of performance increase in Firefox
// at the moment. It may be valuable to turn it on in the future.
var ENABLE_COPYWITHIN = false;

var MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB

var typedArrayToString = (function () {
// This is only for PhantomJS, which doesn't like apply-ing
// with Typed Arrays
Expand Down Expand Up @@ -345,9 +346,49 @@ function Websock() {
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
},

_expand_compact_rQ: function (min_fit) {
var resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
if (resizeNeeded) {
if (!min_fit) {
// just double the size if we need to do compaction
this._rQbufferSize *= 2;
} else {
// otherwise, make sure we satisy rQlen - rQi + min_fit < rQbufferSize / 8
this._rQbufferSize = (this._rQlen - this._rQi + min_fit) * 8;
}
}

// we don't want to grow unboundedly
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
this._rQbufferSize = MAX_RQ_GROW_SIZE;
if (this._rQbufferSize - this._rQlen - this._rQi < min_fit) {
throw new Exception("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
}
}

if (resizeNeeded) {
var old_rQbuffer = this._rQ.buffer;
this._rQmax = this._rQbufferSize / 8;
this._rQ = new Uint8Array(this._rQbufferSize);
this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi));
} else {
if (ENABLE_COPYWITHIN) {
this._rQ.copyWithin(0, this._rQi);
} else {
this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi));
}
}

this._rQlen = this._rQlen - this._rQi;
this._rQi = 0;
},

_decode_message: function (data) {
// push arraybuffer values onto the end
var u8 = new Uint8Array(data);
if (u8.length > this._rQbufferSize - this._rQlen) {
this._expand_compact_rQ(u8.length);
}
this._rQ.set(u8, this._rQlen);
this._rQlen += u8.length;
},
Expand All @@ -362,22 +403,7 @@ function Websock() {
this._rQlen = 0;
this._rQi = 0;
} else if (this._rQlen > this._rQmax) {
if (this._rQlen - this._rQi > 0.5 * this._rQbufferSize) {
var old_rQbuffer = this._rQ.buffer;
this._rQbufferSize *= 2;
this._rQmax = this._rQbufferSize / 8;
this._rQ = new Uint8Array(this._rQbufferSize);
this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi));
} else {
if (ENABLE_COPYWITHIN) {
this._rQ.copyWithin(0, this._rQi);
} else {
this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi));
}
}

this._rQlen = this._rQlen - this._rQi;
this._rQi = 0;
this._expand_compact_rQ();
}
} else {
Util.Debug("Ignoring empty message");
Expand Down

0 comments on commit 5bfdd90

Please sign in to comment.