opcode: improve perf of opcode.from methods.

This commit is contained in:
Christopher Jeffrey 2017-08-20 12:52:35 -07:00
parent 2647d011dc
commit 6c8c18f2a0
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -14,8 +14,7 @@ const common = require('./common');
const BufferReader = require('../utils/reader');
const StaticWriter = require('../utils/staticwriter');
const opcodes = common.opcodes;
const cache = [];
const opCache = [];
/**
* A simple struct which contains
@ -180,92 +179,6 @@ Opcode.prototype.getSize = function getSize() {
}
};
/**
* Inject properties from buffer reader.
* @param {BufferReader} br
* @private
*/
Opcode.prototype.fromReader = function fromReader(br) {
const op = br.readU8();
if (op >= 0x01 && op <= 0x4b) {
if (br.left() < op) {
this.value = -1;
br.seek(br.left());
return this;
}
this.value = op;
this.data = br.readBytes(op);
return this;
}
let size;
switch (op) {
case opcodes.OP_PUSHDATA1:
if (br.left() < 1) {
this.value = -1;
break;
}
size = br.readU8();
if (br.left() < size) {
this.value = -1;
br.seek(br.left());
break;
}
this.value = op;
this.data = br.readBytes(size);
break;
case opcodes.OP_PUSHDATA2:
if (br.left() < 2) {
this.value = -1;
br.seek(br.left());
break;
}
size = br.readU16();
if (br.left() < size) {
this.value = -1;
br.seek(br.left());
break;
}
this.value = op;
this.data = br.readBytes(size);
break;
case opcodes.OP_PUSHDATA4:
if (br.left() < 4) {
this.value = -1;
br.seek(br.left());
break;
}
size = br.readU32();
if (br.left() < size) {
this.value = -1;
br.seek(br.left());
break;
}
this.value = op;
this.data = br.readBytes(size);
break;
default:
this.value = op;
break;
}
return this;
};
/**
* Inject properties from serialized data.
* @private
* @param {Buffer} data
* @returns {Opcode}
*/
Opcode.prototype.fromRaw = function fromRaw(data) {
return this.fromReader(new BufferReader(data));
};
/**
* Instantiate opcode from buffer reader.
* @param {BufferReader} br
@ -273,17 +186,79 @@ Opcode.prototype.fromRaw = function fromRaw(data) {
*/
Opcode.fromReader = function fromReader(br) {
if (br.offset < br.data.length) {
const op = br.data[br.offset];
const cached = cache[op];
const value = br.readU8();
if (cached) {
br.offset++;
return cached;
const cached = opCache[value];
if (cached)
return cached;
const op = new Opcode(value, null);
if (value >= 0x01 && value <= 0x4b) {
if (br.left() < value) {
op.value = -1;
br.seek(br.left());
return op;
}
op.value = value;
op.data = br.readBytes(value);
return op;
}
return new Opcode(0, null).fromReader(br);
let size;
switch (value) {
case opcodes.OP_PUSHDATA1:
if (br.left() < 1) {
op.value = -1;
break;
}
size = br.readU8();
if (br.left() < size) {
op.value = -1;
br.seek(br.left());
break;
}
op.value = value;
op.data = br.readBytes(size);
break;
case opcodes.OP_PUSHDATA2:
if (br.left() < 2) {
op.value = -1;
br.seek(br.left());
break;
}
size = br.readU16();
if (br.left() < size) {
op.value = -1;
br.seek(br.left());
break;
}
op.value = value;
op.data = br.readBytes(size);
break;
case opcodes.OP_PUSHDATA4:
if (br.left() < 4) {
op.value = -1;
br.seek(br.left());
break;
}
size = br.readU32();
if (br.left() < size) {
op.value = -1;
br.seek(br.left());
break;
}
op.value = value;
op.data = br.readBytes(size);
break;
default:
op.value = value;
break;
}
return op;
};
/**
@ -293,15 +268,7 @@ Opcode.fromReader = function fromReader(br) {
*/
Opcode.fromRaw = function fromRaw(data) {
if (data.length > 0) {
const op = data[0];
const cached = cache[op];
if (cached)
return cached;
}
return new Opcode(0, null).fromRaw(data);
return Opcode.fromReader(new BufferReader(data));
};
/**
@ -311,7 +278,7 @@ Opcode.fromRaw = function fromRaw(data) {
*/
Opcode.fromOp = function fromOp(op) {
const cached = cache[op];
const cached = opCache[op];
if (cached)
return cached;
@ -485,15 +452,15 @@ Opcode.isOpcode = function isOpcode(obj) {
for (let value = 0x00; value <= 0xff; value++) {
if (value >= 0x01 && value <= 0x4e) {
cache.push(null);
opCache.push(null);
continue;
}
const op = new Opcode(value);
const op = new Opcode(value, null);
Object.freeze(op);
cache.push(op);
opCache.push(op);
}
/*