gcs: refactor.

This commit is contained in:
Christopher Jeffrey 2017-06-17 17:34:59 -07:00
parent fcc468fb3c
commit 5bf68a765f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -12,6 +12,7 @@ var crypto = require('../crypto/crypto');
var siphash24 = require('../crypto/siphash'); var siphash24 = require('../crypto/siphash');
var SCRATCH = Buffer.allocUnsafe(64); var SCRATCH = Buffer.allocUnsafe(64);
var DUMMY = Buffer.allocUnsafe(0); var DUMMY = Buffer.allocUnsafe(0);
var EOF = new Int64(-1);
/** /**
* GCSFilter * GCSFilter
@ -21,7 +22,7 @@ var DUMMY = Buffer.allocUnsafe(0);
function GCSFilter() { function GCSFilter() {
this.n = 0; this.n = 0;
this.p = 0; this.p = 0;
this.m = Int64(0); this.m = new Int64(0);
this.data = DUMMY; this.data = DUMMY;
} }
@ -41,17 +42,14 @@ GCSFilter.prototype.header = function header(prev) {
GCSFilter.prototype.match = function match(key, data) { GCSFilter.prototype.match = function match(key, data) {
var br = new BitReader(this.data); var br = new BitReader(this.data);
var term = siphash(data, key).imod(this.m); var term = siphash(data, key).imod(this.m);
var last = Int64(0); var last = new Int64(0);
var value; var value;
while (last.lt(term)) { while (last.lt(term)) {
try { value = this.readU64(br);
value = this.readU64(br);
} catch (e) { if (value === EOF)
if (e.message === 'EOF') return false;
return false;
throw e;
}
value.iadd(last); value.iadd(last);
@ -66,7 +64,7 @@ GCSFilter.prototype.match = function match(key, data) {
GCSFilter.prototype.matchAny = function matchAny(key, items) { GCSFilter.prototype.matchAny = function matchAny(key, items) {
var br = new BitReader(this.data); var br = new BitReader(this.data);
var last1 = Int64(0); var last1 = new Int64(0);
var values = []; var values = [];
var i, item, hash, last2, cmp, value; var i, item, hash, last2, cmp, value;
@ -98,13 +96,10 @@ GCSFilter.prototype.matchAny = function matchAny(key, items) {
return false; return false;
} }
try { value = this.readU64(br);
value = this.readU64(br);
} catch (e) { if (value === EOF)
if (e.message === 'EOF') return false;
return false;
throw e;
}
last1.iadd(value); last1.iadd(value);
} }
@ -113,18 +108,26 @@ GCSFilter.prototype.matchAny = function matchAny(key, items) {
}; };
GCSFilter.prototype.readU64 = function readU64(br) { GCSFilter.prototype.readU64 = function readU64(br) {
var num = Int64(0); try {
var bit = br.readBit(); return this._readU64(br);
} catch (e) {
if (e.message === 'EOF')
return EOF;
throw e;
}
};
GCSFilter.prototype._readU64 = function _readU64(br) {
var num = new Int64(0);
var rem; var rem;
while (bit) { // Unary
while (br.readBit())
num.iaddn(1); num.iaddn(1);
bit = br.readBit();
}
rem = br.readBits64(this.p); rem = br.readBits64(this.p);
return num.ishln(this.p).iadd(rem); return num.ishln(this.p).ior(rem);
}; };
GCSFilter.prototype.toBytes = function toBytes() { GCSFilter.prototype.toBytes = function toBytes() {
@ -153,10 +156,16 @@ GCSFilter.prototype.toNPBytes = function toNPBytes() {
return data; return data;
}; };
GCSFilter.prototype.toRaw = function toRaw() {
assert(this.p === 20);
return this.toNBytes();
};
GCSFilter.prototype.fromItems = function fromItems(P, key, items) { GCSFilter.prototype.fromItems = function fromItems(P, key, items) {
var bw = new BitWriter();
var last = new Int64(0);
var values = []; var values = [];
var last = Int64(0); var i, item, hash, value, rem;
var i, bw, item, hash, value, rem;
assert(typeof P === 'number' && isFinite(P)); assert(typeof P === 'number' && isFinite(P));
assert(P >= 0 && P <= 32); assert(P >= 0 && P <= 32);
@ -172,8 +181,6 @@ GCSFilter.prototype.fromItems = function fromItems(P, key, items) {
this.p = P; this.p = P;
this.m = Int64(this.n).ishln(this.p); this.m = Int64(this.n).ishln(this.p);
bw = new BitWriter();
for (i = 0; i < items.length; i++) { for (i = 0; i < items.length; i++) {
item = items[i]; item = items[i];
assert(Buffer.isBuffer(item)); assert(Buffer.isBuffer(item));
@ -254,6 +261,10 @@ GCSFilter.prototype.fromNPBytes = function fromNPBytes(data) {
return this.fromBytes(N, P, data.slice(5)); return this.fromBytes(N, P, data.slice(5));
}; };
GCSFilter.prototype.fromRaw = function fromRaw(data) {
return this.fromNBytes(20, data);
};
GCSFilter.prototype.fromBlock = function fromBlock(block) { GCSFilter.prototype.fromBlock = function fromBlock(block) {
var hash = block.hash(); var hash = block.hash();
var key = hash.slice(0, 16); var key = hash.slice(0, 16);
@ -322,6 +333,10 @@ GCSFilter.fromNPBytes = function fromNPBytes(data) {
return new GCSFilter().fromNPBytes(data); return new GCSFilter().fromNPBytes(data);
}; };
GCSFilter.fromRaw = function fromRaw(data) {
return new GCSFilter().fromRaw(data);
};
GCSFilter.fromBlock = function fromBlock(block) { GCSFilter.fromBlock = function fromBlock(block) {
return new GCSFilter().fromBlock(block); return new GCSFilter().fromBlock(block);
}; };
@ -356,7 +371,7 @@ BitWriter.prototype.writeBit = function writeBit(bit) {
this.remain--; this.remain--;
}; };
BitWriter.prototype.writeOneByte = function writeOneByte(ch) { BitWriter.prototype.writeByte = function writeByte(ch) {
var index; var index;
if (this.remain === 0) { if (this.remain === 0) {
@ -366,9 +381,9 @@ BitWriter.prototype.writeOneByte = function writeOneByte(ch) {
index = this.stream.length - 1; index = this.stream.length - 1;
this.stream[index] |= ch >> (8 - this.remain); this.stream[index] |= (ch >> (8 - this.remain)) & 0xff;
this.stream.push(0); this.stream.push(0);
this.stream[index + 1] = ch << this.remain; this.stream[index + 1] = (ch << this.remain) & 0xff;
}; };
BitWriter.prototype.writeBits = function writeBits(num, count) { BitWriter.prototype.writeBits = function writeBits(num, count) {
@ -381,8 +396,7 @@ BitWriter.prototype.writeBits = function writeBits(num, count) {
while (count >= 8) { while (count >= 8) {
ch = num >>> 24; ch = num >>> 24;
this.writeOneByte(ch); this.writeByte(ch);
num <<= 8; num <<= 8;
count -= 8; count -= 8;
} }
@ -391,11 +405,14 @@ BitWriter.prototype.writeBits = function writeBits(num, count) {
bit = num >>> 31; bit = num >>> 31;
this.writeBit(bit); this.writeBit(bit);
num <<= 1; num <<= 1;
count--; count -= 1;
} }
}; };
BitWriter.prototype.writeBits64 = function writeBits64(num, count) { BitWriter.prototype.writeBits64 = function writeBits64(num, count) {
assert(count >= 0);
assert(count <= 64);
if (count > 32) { if (count > 32) {
this.writeBits(num.hi, count - 32); this.writeBits(num.hi, count - 32);
this.writeBits(num.lo, 32); this.writeBits(num.lo, 32);
@ -405,12 +422,11 @@ BitWriter.prototype.writeBits64 = function writeBits64(num, count) {
}; };
BitWriter.prototype.render = function render() { BitWriter.prototype.render = function render() {
var stream = this.stream; var data = Buffer.allocUnsafe(this.stream.length);
var data = Buffer.allocUnsafe(stream.length);
var i; var i;
for (i = 0; i < stream.length; i++) for (i = 0; i < this.stream.length; i++)
data[i] = stream[i]; data[i] = this.stream[i];
return data; return data;
}; };
@ -421,7 +437,7 @@ BitWriter.prototype.render = function render() {
*/ */
function BitReader(data) { function BitReader(data) {
this.stream = copy(data); this.stream = data;
this.pos = 0; this.pos = 0;
this.remain = 8; this.remain = 8;
} }
@ -441,13 +457,9 @@ BitReader.prototype.readBit = function readBit() {
this.remain = 8; this.remain = 8;
} }
bit = this.stream[this.pos] & 0x80; this.remain -= 1;
this.stream[this.pos] <<= 1; return (this.stream[this.pos] >> this.remain) & 1;
this.stream[this.pos] &= 0xff;
this.remain--;
return bit !== 0 ? 1 : 0;
}; };
BitReader.prototype.readByte = function readByte() { BitReader.prototype.readByte = function readByte() {
@ -471,7 +483,9 @@ BitReader.prototype.readByte = function readByte() {
return ch; return ch;
} }
ch = this.stream[this.pos]; ch = this.stream[this.pos] & ((1 << this.remain) - 1);
ch <<= 8 - this.remain;
this.pos += 1; this.pos += 1;
if (this.pos >= this.stream.length) if (this.pos >= this.stream.length)
@ -479,31 +493,24 @@ BitReader.prototype.readByte = function readByte() {
ch |= this.stream[this.pos] >> this.remain; ch |= this.stream[this.pos] >> this.remain;
this.stream[this.pos] <<= (8 - this.remain);
this.stream[this.pos] &= 0xff;
return ch; return ch;
}; };
BitReader.prototype.readBits = function readBits(count) { BitReader.prototype.readBits = function readBits(count) {
var num = 0; var num = 0;
var ch, bit;
assert(count >= 0); assert(count >= 0);
assert(count <= 32); assert(count <= 32);
while (count >= 8) { while (count >= 8) {
num <<= 8; num <<= 8;
ch = this.readByte(); num |= this.readByte();
num |= ch;
count -= 8; count -= 8;
} }
while (count > 0) { while (count > 0) {
num <<= 1; num <<= 1;
bit = this.readBit(); num |= this.readBit();
if (bit)
num |= 1;
count -= 1; count -= 1;
} }
@ -511,16 +518,19 @@ BitReader.prototype.readBits = function readBits(count) {
}; };
BitReader.prototype.readBits64 = function readBits(count) { BitReader.prototype.readBits64 = function readBits(count) {
var n = new Int64(); var num = new Int64();
assert(count >= 0);
assert(count <= 64);
if (count > 32) { if (count > 32) {
n.hi = this.readBits(count - 32); num.hi = this.readBits(count - 32);
n.lo = this.readBits(32); num.lo = this.readBits(32);
} else { } else {
n.lo = this.readBits(count); num.lo = this.readBits(count);
} }
return n; return num;
}; };
/* /*
@ -532,14 +542,11 @@ function compare(a, b) {
} }
function siphash(data, key) { function siphash(data, key) {
var num = new Int64();
var hash = siphash24(data, key); var hash = siphash24(data, key);
return Int64().join(hash.hi, hash.lo); num.hi = hash.hi | 0;
} num.lo = hash.lo | 0;
return num;
function copy(data) {
var clone = Buffer.allocUnsafe(data.length);
data.copy(clone, 0, 0, data.length);
return clone;
} }
function getPushes(items, script) { function getPushes(items, script) {