More mixing added to FNV-1a.
Lack of sufficient mixing was causing "wtf" to hash poorly in the second hash function, and only map to one location instead of ten.
This commit is contained in:
parent
7d362348c6
commit
19060d93fe
@ -33,10 +33,10 @@
|
||||
a = fnv_1a(v),
|
||||
b = fnv_1a_b(a),
|
||||
i = -1,
|
||||
x;
|
||||
x = a % m;
|
||||
while (++i < k) {
|
||||
x = (a + b * i) % m;
|
||||
r[i] = x < 0 ? x + m : x;
|
||||
r[i] = x < 0 ? (x + m) : x;
|
||||
x = (x + b) % m;
|
||||
}
|
||||
return r;
|
||||
};
|
||||
@ -90,12 +90,23 @@
|
||||
a ^= c & 0xff;
|
||||
a += (a << 1) + (a << 4) + (a << 7) + (a << 8) + (a << 24);
|
||||
}
|
||||
// From http://home.comcast.net/~bretm/hash/6.html
|
||||
a += a << 13;
|
||||
a ^= a >> 7;
|
||||
a += a << 3;
|
||||
a ^= a >> 17;
|
||||
a += a << 5;
|
||||
return a & 0xffffffff;
|
||||
}
|
||||
|
||||
// One additional iteration of FNV, given a hash.
|
||||
function fnv_1a_b(a) {
|
||||
a += (a << 1) + (a << 4) + (a << 7) + (a << 8) + (a << 24);
|
||||
a += a << 13;
|
||||
a ^= a >> 7;
|
||||
a += a << 3;
|
||||
a ^= a >> 17;
|
||||
a += a << 5;
|
||||
return a & 0xffffffff;
|
||||
}
|
||||
})(typeof exports !== "undefined" ? exports : this);
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bloomfilter",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.8",
|
||||
"description": "Fast bloom filter in JavaScript.",
|
||||
"keywords": [
|
||||
"bloom filter",
|
||||
|
@ -1,6 +1,7 @@
|
||||
var bf = require("../bloomfilter"),
|
||||
BloomFilter = bf.BloomFilter,
|
||||
fnv_1a = bf.fnv_1a;
|
||||
fnv_1a = bf.fnv_1a,
|
||||
fnv_1a_b = bf.fnv_1a_b;
|
||||
|
||||
var vows = require("vows"),
|
||||
assert = require("assert");
|
||||
@ -36,52 +37,12 @@ suite.addBatch({
|
||||
assert.equal(f.test(n1), true);
|
||||
assert.equal(f.test(n2), false);
|
||||
assert.equal(f.test(n3), false);
|
||||
}
|
||||
},
|
||||
"fnv": {
|
||||
"basic": function() {
|
||||
// Test vectors from http://isthe.com/chongo/tech/comp/fnv/
|
||||
assert.equal(fnv_1a(""), 0x811c9dc5 & 0xffffffff);
|
||||
assert.equal(fnv_1a("a"), 0xe40c292c & 0xffffffff);
|
||||
assert.equal(fnv_1a("b"), 0xe70c2de5 & 0xffffffff);
|
||||
assert.equal(fnv_1a("c"), 0xe60c2c52 & 0xffffffff);
|
||||
assert.equal(fnv_1a("d"), 0xe10c2473 & 0xffffffff);
|
||||
assert.equal(fnv_1a("e"), 0xe00c22e0 & 0xffffffff);
|
||||
assert.equal(fnv_1a("f"), 0xe30c2799 & 0xffffffff);
|
||||
assert.equal(fnv_1a("fo"), 0x6222e842 & 0xffffffff);
|
||||
assert.equal(fnv_1a("foo"), 0xa9f37ed7 & 0xffffffff);
|
||||
assert.equal(fnv_1a("foob"), 0x3f5076ef & 0xffffffff);
|
||||
assert.equal(fnv_1a("fooba"), 0x39aaa18a & 0xffffffff);
|
||||
assert.equal(fnv_1a("foobar"), 0xbf9cf968 & 0xffffffff);
|
||||
assert.equal(fnv_1a("ch"), 0x5f299f4e & 0xffffffff);
|
||||
assert.equal(fnv_1a("cho"), 0xef8580f3 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chon"), 0xac297727 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chong"), 0x4546b9c0 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo"), 0xbd564e7d & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo "), 0x6bdd5c67 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo w"), 0xdd77ed30 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo wa"), 0xf4ca9683 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo was"), 0x4aeb9bd0 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo was "), 0xe0e67ad0 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo was h"), 0xc2d32fa8 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo was he"), 0x7f743fb7 & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo was her"), 0x6900631f & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo was here"), 0xc59c990e & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo was here!"), 0x448524fd & 0xffffffff);
|
||||
assert.equal(fnv_1a("chongo was here!\n"), 0xd49930d5 & 0xffffffff);
|
||||
assert.equal(fnv_1a(repeat(500, "\x00")), 0xfa823dd5 & 0xffffffff);
|
||||
assert.equal(fnv_1a(repeat(500, "\x07")), 0x21a27271 & 0xffffffff);
|
||||
assert.equal(fnv_1a(repeat(500, "~")), 0x83c5c6d5 & 0xffffffff);
|
||||
assert.equal(fnv_1a(repeat(500, "\x7f")), 0x813b0881 & 0xffffffff);
|
||||
},
|
||||
"wtf": function() {
|
||||
var f = new BloomFilter(20, 10);
|
||||
assert.equal(f.locations("wtf").length, 10);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
suite.export(module);
|
||||
|
||||
function repeat(n, d) {
|
||||
var r = [],
|
||||
i = -1;
|
||||
while (++i < n) r[i] = d;
|
||||
return r.join("");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user