50x performance increase on javascript client prepared statement execution on linux!

This commit is contained in:
brianc 2011-04-16 11:42:23 -05:00
parent 3dc12b71bd
commit 526a6284f9
4 changed files with 71 additions and 31 deletions

View File

@ -78,8 +78,12 @@ p.password = function(password) {
this._send(0x70, this.writer.addCString(password));
};
p._send = function(code, writer) {
return this.stream.write(writer.flush(code));
p._send = function(code, more) {
if(more === true) {
this.writer.addHeader(code);
} else {
return this.stream.write(this.writer.flush(code));
}
}
var termBuffer = new Buffer([0x58, 0, 0, 0, 4]);
@ -92,7 +96,9 @@ p.query = function(text) {
this.stream.write(this.writer.addCString(text).flush(0x51));
};
p.parse = function(query) {
//send parse message
//"more" === true to buffer the message until flush() is called
p.parse = function(query, more) {
//expect something like this:
// { name: 'queryName',
// text: 'select * from blah',
@ -111,13 +117,13 @@ p.parse = function(query) {
buffer.addInt32(query.types[i]);
}
//0x50 = 'P'
this._send(0x50, buffer);
return this;
var code = 0x50;
this._send(code, more);
};
p.bind = function(config) {
//send bind message
//"more" === true to buffer the message until flush() is called
p.bind = function(config, more) {
//normalize config
config = config || {};
config.portal = config.portal || '';
@ -141,11 +147,12 @@ p.bind = function(config) {
}
buffer.addInt16(0); //no format codes, use text
//0x42 = 'B'
this._send(0x42, buffer);
this._send(0x42, more);
};
p.execute = function(config) {
//send execute message
//"more" === true to buffer the message until flush() is called
p.execute = function(config, more) {
config = config || {};
config.portal = config.portal || '';
config.rows = config.rows || '';
@ -154,28 +161,34 @@ p.execute = function(config) {
.addInt32(config.rows);
//0x45 = 'E'
this._send(0x45, buffer);
this._send(0x45, more);
};
var emptyBuffer = Buffer(0);
p.flush = function() {
//0x48 = 'H'
this._send(0x48,this.writer.add(emptyBuffer));
this.writer.add(emptyBuffer)
this._send(0x48);
}
p.sync = function() {
//0x53 = 'S'
this._send(0x53, this.writer.add(emptyBuffer));
//clear out any pending data in the writer
this.writer.flush(0)
this.writer.add(emptyBuffer);
this._send(0x53);
};
p.end = function() {
//0x58 = 'X'
this._send(0x58, this.writer.add(emptyBuffer));
this.writer.add(emptyBuffer);
this._send(0x58);
};
p.describe = function(msg) {
this._send(0x44, this.writer.addCString(msg.type + (msg.name || '')));
p.describe = function(msg, more) {
this.writer.addCString(msg.type + (msg.name || ''));
this._send(0x44, more);
};
//parsing methods

View File

@ -106,7 +106,7 @@ p.getRows = function(connection) {
connection.execute({
portal: this.name,
rows: this.rows
});
}, true);
connection.flush();
};
@ -121,7 +121,7 @@ p.prepare = function(connection) {
text: self.text,
name: self.name,
types: self.types
});
}, true);
connection.parsedStatements[this.name] = true;
}
@ -137,12 +137,12 @@ p.prepare = function(connection) {
portal: self.name,
statement: self.name,
values: self.values
});
}, true);
connection.describe({
type: 'P',
name: self.name || ""
});
}, true);
this.getRows(connection);
};

View File

@ -2,6 +2,7 @@ var Writer = function(size) {
this.size = size || 1024;
this.buffer = new Buffer(this.size + 5);
this.offset = 5;
this.headerPosition = 0;
};
var p = Writer.prototype;
@ -70,18 +71,32 @@ p.add = function(otherBuffer) {
}
p.clear = function() {
this.offset=5;
this.offset = 5;
this.headerPosition = 0;
this.lastEnd = 0;
}
//appends a header block to all the written data since the last
//subsequent header or to the beginning if there is only one data block
p.addHeader = function(code, last) {
var origOffset = this.offset;
this.offset = this.headerPosition;
this.buffer[this.offset++] = code;
//length is everything in this packet minus the code
this.addInt32(origOffset - (this.headerPosition+1))
//set next header position
this.headerPosition = origOffset;
//make space for next header
this.offset = origOffset;
if(!last) {
this._ensure(5);
this.offset += 5;
}
}
p.join = function(code) {
if(code) {
var end = this.offset;
this.offset = 0;
this.buffer[this.offset++] = code;
//write the length which is length of entire packet not including
//message type code byte
this.addInt32(end - 1);
this.offset = end;
this.addHeader(code, true);
}
return this.buffer.slice(code ? 0 : 5, this.offset);
}

View File

@ -156,7 +156,7 @@ test("resizing to much larger", function() {
assert.equalBuffers(result, [33, 33, 33, 33, 33, 33, 33, 33, 0])
})
test("header", function() {
test("flush", function() {
test('added as a hex code to a full writer', function() {
var subject = new Writer(2);
var result = subject.addCString("!").flush(0x50)
@ -175,3 +175,15 @@ test("header", function() {
assert.equalBuffers(result, [0x50, 0, 0, 0, 0x0D, 33, 33, 33, 33, 33, 33, 33, 33, 0]);
})
})
test("header", function() {
test('adding two packets with headers', function() {
var subject = new Writer(10).addCString("!");
subject.addHeader(0x50);
subject.addCString("!!");
subject.addHeader(0x40);
subject.addCString("!");
var result = subject.flush(0x10);
assert.equalBuffers(result, [0x50, 0, 0, 0, 6, 33, 0, 0x40, 0, 0, 0, 7, 33, 33, 0, 0x10, 0, 0, 0, 6, 33, 0 ]);
})
})