gcs: refactor.
This commit is contained in:
parent
fcc468fb3c
commit
5bf68a765f
139
lib/utils/gcs.js
139
lib/utils/gcs.js
@ -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) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user