bloom: do not allow passed in buffer.

This commit is contained in:
Christopher Jeffrey 2017-01-11 14:55:45 -08:00
parent 9efece17d1
commit 4da1e0b4e0
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -27,7 +27,7 @@ var LN2 = 0.6931471805599453094172321214581765680755001343602552;
* Bloom Filter * Bloom Filter
* @exports Bloom * @exports Bloom
* @constructor * @constructor
* @param {Number|Buffer} bits - Filter size in bits, or filter itself. * @param {Number} size - Filter size in bits.
* @param {Number} n - Number of hash functions. * @param {Number} n - Number of hash functions.
* @param {Number} tweak - Seed value. * @param {Number} tweak - Seed value.
* @param {Number|String} - Update type. * @param {Number|String} - Update type.
@ -38,9 +38,9 @@ var LN2 = 0.6931471805599453094172321214581765680755001343602552;
* @property {Number} update - Update flag (see {@link Bloom.flags}). * @property {Number} update - Update flag (see {@link Bloom.flags}).
*/ */
function Bloom(bits, n, tweak, update) { function Bloom(size, n, tweak, update) {
if (!(this instanceof Bloom)) if (!(this instanceof Bloom))
return new Bloom(bits, n, tweak, update); return new Bloom(size, n, tweak, update);
this.filter = DUMMY; this.filter = DUMMY;
this.size = 0; this.size = 0;
@ -48,10 +48,26 @@ function Bloom(bits, n, tweak, update) {
this.tweak = 0; this.tweak = 0;
this.update = Bloom.flags.NONE; this.update = Bloom.flags.NONE;
if (bits != null) if (size != null)
this.fromOptions(bits, n, tweak, update); this.fromOptions(size, n, tweak, update);
} }
/**
* Max bloom filter size.
* @const {Number}
* @default
*/
Bloom.MAX_BLOOM_FILTER_SIZE = 36000;
/**
* Max number of hash functions.
* @const {Number}
* @default
*/
Bloom.MAX_HASH_FUNCS = 50;
/** /**
* Bloom filter update flags. * Bloom filter update flags.
* @enum {Number} * @enum {Number}
@ -90,46 +106,27 @@ Bloom.flagsByVal = {
2: 'PUBKEY_ONLY' 2: 'PUBKEY_ONLY'
}; };
/**
* Max bloom filter size.
* @const {Number}
* @default
*/
Bloom.MAX_BLOOM_FILTER_SIZE = 36000;
/**
* Max number of hash functions.
* @const {Number}
* @default
*/
Bloom.MAX_HASH_FUNCS = 50;
/** /**
* Inject properties from options. * Inject properties from options.
* @private * @private
* @param {Number|Buffer} bits - Filter size in bits, or filter itself. * @param {Number} size - Filter size in bits.
* @param {Number} n - Number of hash functions. * @param {Number} n - Number of hash functions.
* @param {Number} tweak - Seed value. * @param {Number} tweak - Seed value.
* @param {Number|String} - Update type. * @param {Number|String} - Update type.
* @returns {Bloom} * @returns {Bloom}
*/ */
Bloom.prototype.fromOptions = function fromOptions(bits, n, tweak, update) { Bloom.prototype.fromOptions = function fromOptions(size, n, tweak, update) {
var filter, size; var filter;
if (Buffer.isBuffer(bits)) { assert(typeof size === 'number', '`size` must be a number.');
filter = bits; assert(size > 0, '`size` must be greater than zero.');
size = filter.length * 8; assert(size % 1 === 0, '`size` must be an integer.');
} else {
assert(typeof bits === 'number', '`bits` must be a number or Buffer.'); size -= size % 8;
assert(bits > 0, '`bits` must be greater than zero.');
size = bits; filter = new Buffer(size / 8);
size -= size % 8; filter.fill(0);
filter = new Buffer(size / 8);
filter.fill(0);
}
if (tweak == null || tweak === -1) if (tweak == null || tweak === -1)
tweak = (Math.random() * 0x100000000) >>> 0; tweak = (Math.random() * 0x100000000) >>> 0;
@ -144,7 +141,9 @@ Bloom.prototype.fromOptions = function fromOptions(bits, n, tweak, update) {
assert(size > 0, '`size` must be greater than zero.'); assert(size > 0, '`size` must be greater than zero.');
assert(n > 0, '`n` must be greater than zero.'); assert(n > 0, '`n` must be greater than zero.');
assert(n % 1 === 0, '`n` must be an integer.');
assert(typeof tweak === 'number', '`tweak` must be a number.'); assert(typeof tweak === 'number', '`tweak` must be a number.');
assert(tweak % 1 === 0, '`tweak` must be an integer.');
assert(Bloom.flagsByVal[update], 'Unknown update flag.'); assert(Bloom.flagsByVal[update], 'Unknown update flag.');
this.filter = filter; this.filter = filter;
@ -158,15 +157,15 @@ Bloom.prototype.fromOptions = function fromOptions(bits, n, tweak, update) {
/** /**
* Instantiate bloom filter from options. * Instantiate bloom filter from options.
* @param {Number|Buffer} bits - Filter size in bits, or filter itself. * @param {Number} size - Filter size in bits.
* @param {Number} n - Number of hash functions. * @param {Number} n - Number of hash functions.
* @param {Number} tweak - Seed value. * @param {Number} tweak - Seed value.
* @param {Number|String} - Update type. * @param {Number|String} - Update type.
* @returns {Bloom} * @returns {Bloom}
*/ */
Bloom.fromOptions = function fromOptions(bits, n, tweak, update) { Bloom.fromOptions = function fromOptions(size, n, tweak, update) {
return new Bloom().fromOptions(bits, n, tweak, update); return new Bloom().fromOptions(size, n, tweak, update);
}; };
/** /**
@ -266,6 +265,12 @@ Bloom.prototype.added = function added(val, enc) {
Bloom.fromRate = function fromRate(items, rate, update) { Bloom.fromRate = function fromRate(items, rate, update) {
var size, n; var size, n;
assert(typeof items === 'number', '`items` must be a number.');
assert(items > 0, '`items` must be greater than zero.');
assert(items % 1 === 0, '`items` must be an integer.');
assert(typeof rate === 'number', '`rate` must be a number.');
assert(rate >= 0 && rate <= 1, '`rate` must be between 0.0 and 1.0.');
size = (-1 / LN2SQUARED * items * Math.log(rate)) | 0; size = (-1 / LN2SQUARED * items * Math.log(rate)) | 0;
if (update !== -1) if (update !== -1)
@ -409,12 +414,13 @@ function RollingFilter(items, rate) {
*/ */
RollingFilter.prototype.fromRate = function fromRate(items, rate) { RollingFilter.prototype.fromRate = function fromRate(items, rate) {
var logRate, max, n, limit, size, items, tweak, filter; var logRate, max, n, limit, size, tweak, filter;
assert(typeof items === 'number', '`items` must be a number.'); assert(typeof items === 'number', '`items` must be a number.');
assert(items > 0, '`items` must be greater than zero.'); assert(items > 0, '`items` must be greater than zero.');
assert(items % 1 === 0, '`items` must be an integer.');
assert(typeof rate === 'number', '`rate` must be a number.'); assert(typeof rate === 'number', '`rate` must be a number.');
assert(rate >= 0, '`rate` must be positive.'); assert(rate >= 0 && rate <= 1, '`rate` must be between 0.0 and 1.0.');
logRate = Math.log(rate); logRate = Math.log(rate);