1 | "use strict";
|
2 |
|
3 | var BitBuffer = require('bitbuffer').BitBuffer
|
4 | var VNF = require('fnv').FNV
|
5 |
|
6 | function calculateSize(capacity, error_rate) {
|
7 | var log2sq = 0.480453
|
8 | return Math.ceil(capacity * Math.log(error_rate) / -log2sq)
|
9 | }
|
10 |
|
11 | function calculateSlices(size, capacity) {
|
12 | return size / capacity * Math.log(2)
|
13 | }
|
14 |
|
15 | function calulateHashes(key, size, slices) {
|
16 | |
17 |
|
18 |
|
19 |
|
20 |
|
21 | function fnv(seed, data) {
|
22 | var h = new VNF()
|
23 | h.update(seed)
|
24 | h.update(data)
|
25 | return h.value()
|
26 | }
|
27 | var h1 = fnv(Buffer("S"), key)
|
28 | var h2 = fnv(Buffer("W"), key)
|
29 | var hashes = []
|
30 | for(var i = 0; i < slices; i++) {
|
31 | hashes.push((h1 + i * h2) % size)
|
32 | }
|
33 | return hashes
|
34 | }
|
35 |
|
36 | function Bloem(size, slices) {
|
37 | this.size = size
|
38 | this.slices = slices
|
39 | this.bitfield = new BitBuffer(size)
|
40 | }
|
41 |
|
42 | Bloem.prototype = {
|
43 | add: function(key) {
|
44 | var hashes = calulateHashes(key, this.size, this.slices)
|
45 | for(var i = 0; i < hashes.length; i++) {
|
46 | this.bitfield.set(hashes[i], true)
|
47 | }
|
48 | },
|
49 | has: function(key) {
|
50 | var hashes = calulateHashes(key, this.size, this.slices)
|
51 | for(var i = 0; i < hashes.length; i++) {
|
52 | if(!this.bitfield.get(hashes[i])) return false
|
53 | }
|
54 | return true
|
55 | }
|
56 | }
|
57 |
|
58 | exports.Bloem = Bloem
|
59 | exports.calculateSize = calculateSize
|
60 | exports.calculateSlices = calculateSlices |
\ | No newline at end of file |