|
1 | 1 | var JSBloom = {}; |
2 | 2 |
|
3 | | -JSBloom.filter = function(items, target_prob) { |
| 3 | +JSBloom.filter = function (items, target_prob) { |
4 | 4 |
|
5 | 5 | if (typeof items !== "number" || typeof target_prob !== "number" || target_prob >= 1) { |
6 | 6 | throw Error("Usage: new JSBloom.filter(items, target_probability)"); |
7 | 7 | }; |
8 | 8 |
|
9 | | - var BUFFER_LEN = (function() { |
10 | | - var buffer = Math.ceil((items * Math.log(target_prob)) / Math.log(1.0 / (Math.pow(2.0, Math.log(2.0))))); |
| 9 | + var BUFFER_LEN = (function () { |
| 10 | + var buffer = Math.ceil((items * Math.log(target_prob)) / Math.log(1.0 / (Math.pow(2.0, Math.log(2.0))))); |
11 | 11 |
|
12 | | - if ((buffer % 8) !== 0) { |
13 | | - buffer += 8 - (buffer % 8); |
14 | | - }; |
15 | | - |
16 | | - return buffer; |
17 | | - })(), |
18 | | - HASH_ROUNDS = Math.round(Math.log(2.0) * BUFFER_LEN / items), |
19 | | - bVector = new Uint8Array(BUFFER_LEN/8); |
20 | | - |
21 | | - hashes = { |
22 | | - djb2: function(str) { |
23 | | - var hash = 5381; |
24 | | - |
25 | | - for (var len = str.length, count = 0; count < len; count++) { |
26 | | - hash = hash * 33 ^ str.charCodeAt(count); |
27 | | - }; |
28 | | - |
29 | | - return (hash >>> 0) % BUFFER_LEN; |
30 | | - }, |
31 | | - sdbm: function(str) { |
32 | | - var hash = 0; |
| 12 | + if ((buffer % 8) !== 0) { |
| 13 | + buffer += 8 - (buffer % 8); |
| 14 | + }; |
33 | 15 |
|
34 | | - for (var len = str.length, count = 0; count < len; count++) { |
35 | | - hash = str.charCodeAt(count) + (hash << 6) + (hash << 16) - hash; |
36 | | - }; |
| 16 | + return buffer; |
| 17 | + })(), |
| 18 | + HASH_ROUNDS = Math.round(Math.log(2.0) * BUFFER_LEN / items), |
| 19 | + bVector = new Uint8Array(BUFFER_LEN / 8), |
37 | 20 |
|
38 | | - return (hash >>> 0) % BUFFER_LEN; |
39 | | - } |
40 | | - } |
| 21 | + hashes = { |
| 22 | + djb2: function (str) { |
| 23 | + var hash = 5381; |
41 | 24 |
|
42 | | - addEntry = function(str) { |
| 25 | + for (var len = str.length, count = 0; count < len; count++) { |
| 26 | + hash = hash * 33 ^ str.charCodeAt(count); |
| 27 | + }; |
43 | 28 |
|
44 | | - var h1 = hashes.djb2(str) |
45 | | - var h2 = hashes.sdbm(str) |
46 | | - var added = false |
47 | | - for (var round = 0; round <= HASH_ROUNDS; round++) { |
48 | | - var new_hash = round == 0 ? h1 |
49 | | - : round == 1 ? h2 |
50 | | - : (h1 + (round * h2) + (round^2)) % BUFFER_LEN; |
| 29 | + return (hash >>> 0) % BUFFER_LEN; |
| 30 | + }, |
| 31 | + sdbm: function (str) { |
| 32 | + var hash = 0; |
51 | 33 |
|
52 | | - var extra_indices = new_hash % 8, |
53 | | - index = ((new_hash - extra_indices) / 8); |
| 34 | + for (var len = str.length, count = 0; count < len; count++) { |
| 35 | + hash = str.charCodeAt(count) + (hash << 6) + (hash << 16) - hash; |
| 36 | + }; |
54 | 37 |
|
55 | | - if (extra_indices != 0 && (bVector[index] & (128 >> (extra_indices - 1))) == 0) { |
56 | | - bVector[index] ^= (128 >> extra_indices - 1); |
57 | | - added = true; |
58 | | - } else if (extra_indices == 0 && (bVector[index] & 1) == 0) { |
59 | | - bVector[index] ^= 1; |
60 | | - added = true; |
| 38 | + return (hash >>> 0) % BUFFER_LEN; |
61 | 39 | } |
| 40 | + }, |
62 | 41 |
|
63 | | - }; |
64 | | - |
65 | | - return added; |
66 | | - } |
67 | | - |
68 | | - addEntries = function(arr) { |
69 | | - for (var i = arr.length - 1; i >= 0; i--) { |
70 | | - |
71 | | - addEntry(arr[i]); |
| 42 | + addEntry = function (str) { |
| 43 | + var h1 = hashes.djb2(str) |
| 44 | + var h2 = hashes.sdbm(str) |
| 45 | + var added = false |
| 46 | + for (var round = 0; round <= HASH_ROUNDS; round++) { |
| 47 | + var new_hash = round == 0 ? h1 |
| 48 | + : round == 1 ? h2 |
| 49 | + : (h1 + (round * h2) + (round ^ 2)) % BUFFER_LEN; |
| 50 | + |
| 51 | + var extra_indices = new_hash % 8, |
| 52 | + index = ((new_hash - extra_indices) / 8); |
| 53 | + |
| 54 | + if (extra_indices != 0 && (bVector[index] & (128 >> (extra_indices - 1))) == 0) { |
| 55 | + bVector[index] ^= (128 >> extra_indices - 1); |
| 56 | + added = true; |
| 57 | + } else if (extra_indices == 0 && (bVector[index] & 1) == 0) { |
| 58 | + bVector[index] ^= 1; |
| 59 | + added = true; |
| 60 | + } |
72 | 61 |
|
73 | | - }; |
| 62 | + }; |
74 | 63 |
|
75 | | - return true; |
76 | | - } |
| 64 | + return added; |
| 65 | + }, |
77 | 66 |
|
78 | | - checkEntry = function(str) { |
79 | | - var index, extra_indices |
80 | | - var h1 = hashes.djb2(str) |
| 67 | + addEntries = function (arr) { |
| 68 | + for (var i = arr.length - 1; i >= 0; i--) { |
| 69 | + addEntry(arr[i]); |
| 70 | + }; |
81 | 71 |
|
82 | | - extra_indices = h1 % 8; |
83 | | - index = ((h1 - extra_indices) / 8); |
| 72 | + return true; |
| 73 | + }, |
84 | 74 |
|
85 | | - if (extra_indices != 0 && (bVector[index] & (128 >> (extra_indices - 1))) == 0) { |
86 | | - return false; |
87 | | - } else if (extra_indices == 0 && (bVector[index] & 1) == 0) { |
88 | | - return false; |
89 | | - } |
| 75 | + checkEntry = function (str) { |
| 76 | + var index, extra_indices |
| 77 | + var h1 = hashes.djb2(str) |
90 | 78 |
|
91 | | - var h2 = hashes.sdbm(str) |
92 | | - extra_indices = h2 % 8; |
93 | | - index = ((h2 - extra_indices) / 8); |
| 79 | + extra_indices = h1 % 8; |
| 80 | + index = ((h1 - extra_indices) / 8); |
94 | 81 |
|
95 | | - if (extra_indices != 0 && (bVector[index] & (128 >> (extra_indices - 1))) == 0) { |
96 | | - return false; |
97 | | - } else if (extra_indices == 0 && (bVector[index] & 1) == 0) { |
98 | | - return false; |
99 | | - } |
| 82 | + if (extra_indices != 0 && (bVector[index] & (128 >> (extra_indices - 1))) == 0) { |
| 83 | + return false; |
| 84 | + } else if (extra_indices == 0 && (bVector[index] & 1) == 0) { |
| 85 | + return false; |
| 86 | + } |
100 | 87 |
|
101 | | - for (var round = 2; round <= HASH_ROUNDS; round++) { |
102 | | - var new_hash = round==0?h1:round==1?h2:(h1 + (round * h2) + (round^2)) % BUFFER_LEN; |
103 | | - var extra_indices = new_hash % 8, |
104 | | - index = ((new_hash - extra_indices) / 8); |
| 88 | + var h2 = hashes.sdbm(str) |
| 89 | + extra_indices = h2 % 8; |
| 90 | + index = ((h2 - extra_indices) / 8); |
105 | 91 |
|
106 | 92 | if (extra_indices != 0 && (bVector[index] & (128 >> (extra_indices - 1))) == 0) { |
107 | 93 | return false; |
108 | 94 | } else if (extra_indices == 0 && (bVector[index] & 1) == 0) { |
109 | 95 | return false; |
110 | 96 | } |
111 | | - }; |
112 | 97 |
|
113 | | - return true; |
114 | | - } |
| 98 | + for (var round = 2; round <= HASH_ROUNDS; round++) { |
| 99 | + var new_hash = round == 0 ? h1 : round == 1 ? h2 : (h1 + (round * h2) + (round ^ 2)) % BUFFER_LEN; |
| 100 | + var extra_indices = new_hash % 8, |
| 101 | + index = ((new_hash - extra_indices) / 8); |
| 102 | + |
| 103 | + if (extra_indices != 0 && (bVector[index] & (128 >> (extra_indices - 1))) == 0) { |
| 104 | + return false; |
| 105 | + } else if (extra_indices == 0 && (bVector[index] & 1) == 0) { |
| 106 | + return false; |
| 107 | + } |
| 108 | + }; |
| 109 | + |
| 110 | + return true; |
| 111 | + }, |
115 | 112 |
|
116 | | - importData = function(data) { |
117 | | - bVector = data |
118 | | - } |
| 113 | + importData = function (data) { |
| 114 | + bVector = data |
| 115 | + }, |
119 | 116 |
|
120 | | - exportData = function() { |
121 | | - return bVector |
122 | | - } |
| 117 | + exportData = function () { |
| 118 | + return bVector |
| 119 | + }; |
123 | 120 |
|
124 | 121 | return { |
125 | 122 | info: { |
|
0 commit comments