json-bloomfilter 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +23 -1
- data/README.md +80 -1
- data/Rakefile +9 -1
- data/coffee/bitarray.coffee +6 -2
- data/coffee/bloomfilter.coffee +1 -1
- data/coffee/zlib.coffee +0 -4
- data/js/json-bloomfilter.min.js +1 -1
- data/json-bloomfilter.gemspec +1 -0
- data/lib/json/bloomfilter/bitarray.rb +0 -3
- data/lib/json/bloomfilter/version.rb +1 -1
- data/pkg/json-bloomfilter-0.0.3.gem +0 -0
- data/spec/javascripts/bitarray_spec.js +70 -0
- data/spec/javascripts/bloomfilter_spec.js +75 -0
- data/spec/javascripts/support/jasmine.yml +8 -0
- data/spec/javascripts/zlib_spec.js +10 -0
- data/spec/json/bloomfilter/bitarray_spec.rb +3 -3
- metadata +28 -3
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
json-bloomfilter (0.0.
|
4
|
+
json-bloomfilter (0.0.4)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -10,6 +10,9 @@ GEM
|
|
10
10
|
Platform (>= 0.4.0)
|
11
11
|
open4
|
12
12
|
Platform (0.4.0)
|
13
|
+
addressable (2.3.2)
|
14
|
+
childprocess (0.3.6)
|
15
|
+
ffi (~> 1.0, >= 1.0.6)
|
13
16
|
coffee-script (2.2.0)
|
14
17
|
coffee-script-source
|
15
18
|
execjs
|
@@ -17,10 +20,21 @@ GEM
|
|
17
20
|
diff-lcs (1.1.3)
|
18
21
|
execjs (1.4.0)
|
19
22
|
multi_json (~> 1.0)
|
23
|
+
ffi (1.3.1)
|
20
24
|
fssm (0.2.9)
|
25
|
+
jasmine (1.3.1)
|
26
|
+
jasmine-core (~> 1.3.1)
|
27
|
+
rack (~> 1.0)
|
28
|
+
rspec (>= 1.3.1)
|
29
|
+
selenium-webdriver (>= 0.1.3)
|
30
|
+
jasmine-core (1.3.1)
|
21
31
|
libv8 (3.11.8.13)
|
32
|
+
libwebsocket (0.1.7.1)
|
33
|
+
addressable
|
34
|
+
websocket
|
22
35
|
multi_json (1.5.0)
|
23
36
|
open4 (1.3.0)
|
37
|
+
rack (1.4.4)
|
24
38
|
rake (10.0.3)
|
25
39
|
rb-fsevent (0.9.3)
|
26
40
|
ref (1.0.2)
|
@@ -32,9 +46,16 @@ GEM
|
|
32
46
|
rspec-expectations (2.12.1)
|
33
47
|
diff-lcs (~> 1.1.3)
|
34
48
|
rspec-mocks (2.12.1)
|
49
|
+
rubyzip (0.9.9)
|
50
|
+
selenium-webdriver (2.27.2)
|
51
|
+
childprocess (>= 0.2.5)
|
52
|
+
libwebsocket (~> 0.1.3)
|
53
|
+
multi_json (~> 1.0)
|
54
|
+
rubyzip
|
35
55
|
therubyracer (0.11.3)
|
36
56
|
libv8 (~> 3.11.8.12)
|
37
57
|
ref
|
58
|
+
websocket (1.0.6)
|
38
59
|
yui-compressor (0.9.6)
|
39
60
|
POpen4 (>= 0.1.4)
|
40
61
|
|
@@ -44,6 +65,7 @@ PLATFORMS
|
|
44
65
|
DEPENDENCIES
|
45
66
|
coffee-script
|
46
67
|
fssm
|
68
|
+
jasmine
|
47
69
|
json-bloomfilter!
|
48
70
|
rake
|
49
71
|
rb-fsevent
|
data/README.md
CHANGED
@@ -1,9 +1,88 @@
|
|
1
1
|
# JSON Bloomfilter
|
2
2
|
|
3
|
-
A
|
3
|
+
A BloomFilter implementation that is serialisable to JSON and compatible between both Ruby and Javascript. Very useful when needing to train a bloom filter in one language and using it in the other.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
### Installation
|
8
|
+
|
9
|
+
```shell
|
10
|
+
gem install json-bloomfilter
|
11
|
+
```
|
12
|
+
|
13
|
+
or
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'json-bloomfilter'
|
17
|
+
```
|
18
|
+
|
19
|
+
in your Gemfile
|
20
|
+
|
21
|
+
### Ruby
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# create a new BloomFilter and add entries
|
25
|
+
filter = JsonBloomFilter.new size: 100
|
26
|
+
filter.add "foo"
|
27
|
+
filter.add "bar"
|
28
|
+
filter.test "foo" #=> true
|
29
|
+
filter.test "bar" #=> true
|
30
|
+
filter.test "doh" #=> probably false
|
31
|
+
|
32
|
+
# export the filter to a hash or json
|
33
|
+
filter.to_json #=> hash as JSON
|
34
|
+
config = filter.to_hash #=> { "size" => 100, "hashes" => 4, "seed" => 1234567890, "bits" => [...] }
|
35
|
+
|
36
|
+
# use the hash to generate a new BloomFilter with the same config
|
37
|
+
filter2 = JsonBloomFilter.new config
|
38
|
+
filter2.test "foo" #=> true
|
39
|
+
filter2.test "bar" #=> true
|
40
|
+
filter2.test "doh" #=> probably false
|
41
|
+
```
|
42
|
+
|
43
|
+
### Javascript
|
44
|
+
|
45
|
+
```javascript
|
46
|
+
# create a new BloomFilter and add entries
|
47
|
+
filter = new JsonBloomFilter({ size: 100 });
|
48
|
+
filter.add("foo");
|
49
|
+
filter.add("bar");
|
50
|
+
filter.test("foo"); #=> true
|
51
|
+
filter.test("bar"); #=> true
|
52
|
+
filter.test("doh"); #=> probably false
|
53
|
+
|
54
|
+
# export the filter to a hash or json
|
55
|
+
filter.toJson(); #=> hash as JSON
|
56
|
+
config = filter.toHash(); #=> { "size" => 100, "hashes" => 4, "seed" => 1234567890, "bits" => [...] }
|
57
|
+
|
58
|
+
# use the hash to generate a new BloomFilter with the same config
|
59
|
+
filter2 = new JsonBloomFilter(config);
|
60
|
+
filter2.test("foo"); #=> true
|
61
|
+
filter2.test("bar"); #=> true
|
62
|
+
filter2.test("doh") #=> probably false
|
63
|
+
```
|
64
|
+
|
65
|
+
### Options
|
66
|
+
|
67
|
+
Valid options for constructor are:
|
68
|
+
|
69
|
+
* `size` (default: 100), the number of items intended to store in the
|
70
|
+
* `hashes` (default: 4), the number of hashes used to calculate the bit positions in the bit field
|
71
|
+
* `seed` (default: current UNIX time), the seed for the hashing method
|
72
|
+
|
73
|
+
Additionally you can pass along:
|
74
|
+
|
75
|
+
* `bits` (default: null), an array with the bitfield in non-bit format. Use `#to_hash` to create these for your active BloomFilter.
|
76
|
+
|
77
|
+
## Credits
|
78
|
+
|
79
|
+
* bitarray.rb and bitarray.coffee based on [version by Peter Cooper](https://github.com/peterc/bitarray).
|
80
|
+
* bloomfilter.rb and bloomfilter.coffee inspired by [Ilya Grigorik's Redis Bloomfilter](https://github.com/igrigorik/bloomfilter-rb/blob/master/lib/bloomfilter/redis.rb)
|
81
|
+
* zlib.coffee crc32 method based on the [node-crc32](https://github.com/mikepulaski/node-crc32) library and [this snippet](http://stackoverflow.com/questions/6226189/how-to-convert-a-string-to-bytearray/10132540#10132540)
|
4
82
|
|
5
83
|
## Release notes
|
6
84
|
|
85
|
+
* **0.0.4** Added JS tests
|
7
86
|
* **0.0.3** Added Ruby tests
|
8
87
|
* **0.0.2** First implementation of both Ruby and JS filters
|
9
88
|
* **0.0.1** Skeleton
|
data/Rakefile
CHANGED
@@ -80,4 +80,12 @@ namespace :js do
|
|
80
80
|
File.delete js_file
|
81
81
|
end
|
82
82
|
|
83
|
-
end
|
83
|
+
end
|
84
|
+
begin
|
85
|
+
require 'jasmine'
|
86
|
+
load 'jasmine/tasks/jasmine.rake'
|
87
|
+
rescue LoadError
|
88
|
+
task :jasmine do
|
89
|
+
abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine"
|
90
|
+
end
|
91
|
+
end
|
data/coffee/bitarray.coffee
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
JsonBloomfilter.BitArray = (size, field = null) ->
|
2
|
+
throw new Error("Missing argument: size") unless size
|
3
|
+
|
2
4
|
@ELEMENT_WIDTH = 32
|
3
5
|
@size = size
|
4
6
|
@field = field || []
|
5
7
|
|
6
8
|
arrayLength = Math.floor(((size - 1) / @ELEMENT_WIDTH) + 1)
|
7
|
-
@field[i] = 0 for i in [0..arrayLength] unless field
|
9
|
+
@field[i] = 0 for i in [0..arrayLength-1] unless field
|
8
10
|
|
9
11
|
this
|
10
12
|
|
@@ -15,15 +17,17 @@ JsonBloomfilter.BitArray.prototype.remove = (position) ->
|
|
15
17
|
@set(position, 0)
|
16
18
|
|
17
19
|
JsonBloomfilter.BitArray.prototype.set = (position, value) ->
|
20
|
+
throw new Error("BitArray index out of bounds") if position >= @size
|
18
21
|
aPos = @arrayPosition(position)
|
19
22
|
bChange = @bitChange(position)
|
20
23
|
if value == 1
|
21
24
|
@field[aPos] |= bChange
|
22
|
-
else if @field[aPos] & bChange != 0
|
25
|
+
else if (@field[aPos] & bChange) != 0
|
23
26
|
@field[aPos] ^= bChange
|
24
27
|
true
|
25
28
|
|
26
29
|
JsonBloomfilter.BitArray.prototype.get = (position) ->
|
30
|
+
throw new Error("BitArray index out of bounds") if position >= @size
|
27
31
|
aPos = @arrayPosition(position)
|
28
32
|
bChange = @bitChange(position)
|
29
33
|
if (@field[aPos] & bChange) > 0
|
data/coffee/bloomfilter.coffee
CHANGED
data/coffee/zlib.coffee
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
# Based of:
|
2
|
-
# https://github.com/mikepulaski/node-crc32
|
3
|
-
# http://stackoverflow.com/questions/6226189/how-to-convert-a-string-to-bytearray/10132540#10132540
|
4
|
-
|
5
1
|
JsonBloomfilter.Zlib =
|
6
2
|
CRC32_TABLE: new Array(0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D)
|
7
3
|
|
data/js/json-bloomfilter.min.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var JsonBloomfilter;JsonBloomfilter=function(options){var key,value;if(options==null){options={}}this.options={size:100,hashes:4,seed:new Date().getTime()/1000,bits:null};for(key in options){value=options[key];this.options[key]=value}this.bits=new JsonBloomfilter.BitArray(this.options.size,this.options.bits);return this};JsonBloomfilter.prototype.add=function(key){var index,_i,_len,_ref;_ref=this.indexesFor(key);for(_i=0,_len=_ref.length;_i<_len;_i++){index=_ref[_i];this.bits.add(index)}};JsonBloomfilter.prototype.test=function(key){var index,_i,_len,_ref;_ref=this.indexesFor(key);for(_i=0,_len=_ref.length;_i<_len;_i++){index=_ref[_i];if(this.bits.get(index)===0){return false}}return true};JsonBloomfilter.prototype.clear=function(){this.bits=
|
1
|
+
var JsonBloomfilter;JsonBloomfilter=function(options){var key,value;if(options==null){options={}}this.options={size:100,hashes:4,seed:new Date().getTime()/1000,bits:null};for(key in options){value=options[key];this.options[key]=value}this.bits=new JsonBloomfilter.BitArray(this.options.size,this.options.bits);return this};JsonBloomfilter.prototype.add=function(key){var index,_i,_len,_ref;_ref=this.indexesFor(key);for(_i=0,_len=_ref.length;_i<_len;_i++){index=_ref[_i];this.bits.add(index)}};JsonBloomfilter.prototype.test=function(key){var index,_i,_len,_ref;_ref=this.indexesFor(key);for(_i=0,_len=_ref.length;_i<_len;_i++){index=_ref[_i];if(this.bits.get(index)===0){return false}}return true};JsonBloomfilter.prototype.clear=function(){this.bits=new JsonBloomfilter.BitArray(this.options.size)};JsonBloomfilter.prototype.toHash=function(){var hash,key,value,_ref;hash={};_ref=this.options;for(key in _ref){value=_ref[key];hash[key]=value}hash.bits=this.bits.field;return hash};JsonBloomfilter.prototype.toJson=function(){return JSON.stringify(this.toHash())};JsonBloomfilter.prototype.indexesFor=function(key){var index,indexes,_i,_ref;indexes=[];for(index=_i=0,_ref=this.options.hashes-1;0<=_ref?_i<=_ref:_i>=_ref;index=0<=_ref?++_i:--_i){indexes.push(JsonBloomfilter.Zlib.crc32(""+key+":"+(index+this.options.seed))%this.options.size)}return indexes};JsonBloomfilter.BitArray=function(size,field){var arrayLength,i,_i,_ref;if(field==null){field=null}if(!size){throw new Error("Missing argument: size")}this.ELEMENT_WIDTH=32;this.size=size;this.field=field||[];arrayLength=Math.floor(((size-1)/this.ELEMENT_WIDTH)+1);if(!field){for(i=_i=0,_ref=arrayLength-1;0<=_ref?_i<=_ref:_i>=_ref;i=0<=_ref?++_i:--_i){this.field[i]=0}}return this};JsonBloomfilter.BitArray.prototype.add=function(position){return this.set(position,1)};JsonBloomfilter.BitArray.prototype.remove=function(position){return this.set(position,0)};JsonBloomfilter.BitArray.prototype.set=function(position,value){var aPos,bChange;if(position>=this.size){throw new Error("BitArray index out of bounds")}aPos=this.arrayPosition(position);bChange=this.bitChange(position);if(value===1){this.field[aPos]|=bChange}else{if((this.field[aPos]&bChange)!==0){this.field[aPos]^=bChange}}return true};JsonBloomfilter.BitArray.prototype.get=function(position){var aPos,bChange;if(position>=this.size){throw new Error("BitArray index out of bounds")}aPos=this.arrayPosition(position);bChange=this.bitChange(position);if((this.field[aPos]&bChange)>0){return 1}else{return 0}};JsonBloomfilter.BitArray.prototype.arrayPosition=function(position){return Math.floor(position/this.ELEMENT_WIDTH)};JsonBloomfilter.BitArray.prototype.bitChange=function(position){return Math.abs(1<<position%this.ELEMENT_WIDTH)};JsonBloomfilter.BitArray.prototype.toString=function(){var i,output,_i,_ref;output="";for(i=_i=0,_ref=this.size-1;0<=_ref?_i<=_ref:_i>=_ref;i=0<=_ref?++_i:--_i){output+=this.get(i)}return output};JsonBloomfilter.Zlib={CRC32_TABLE:new Array(0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918000,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117),crc32:function(string){var bytes,crc,i,iTop,n;bytes=this.bytesFor(string);crc=0;n=0;crc=crc^(-1);i=0;iTop=bytes.length;while(i<iTop){n=(crc^bytes[i])&255;crc=(crc>>>8)^this.CRC32_TABLE[n];i++}crc=crc^(-1);if(crc<0){crc+=4294967296}return crc},bytesFor:function(string){var bytes,i;bytes=[];i=0;while(i<string.length){bytes.push(string.charCodeAt(i));++i}return bytes}};
|
data/json-bloomfilter.gemspec
CHANGED
Binary file
|
@@ -0,0 +1,70 @@
|
|
1
|
+
describe("JsonBloomfilter.BitArray", function() {
|
2
|
+
|
3
|
+
describe("#initialize", function() {
|
4
|
+
it("should require a size", function() {
|
5
|
+
expect(function(){new JsonBloomfilter.BitArray()}).toThrow("Missing argument: size")
|
6
|
+
});
|
7
|
+
|
8
|
+
it("should take an optional bit field", function() {
|
9
|
+
field = [0,0,0,2];
|
10
|
+
ba = new JsonBloomfilter.BitArray(100, field);
|
11
|
+
expect(ba.field).toBe(field);
|
12
|
+
});
|
13
|
+
|
14
|
+
it("should create the right size field"), function() {
|
15
|
+
ba = new JsonBloomfilter.BitArray(100);
|
16
|
+
expect(ba.field.length).toBe(4);
|
17
|
+
});
|
18
|
+
});
|
19
|
+
|
20
|
+
describe("#add", function() {
|
21
|
+
it("should set the bit to 1", function() {
|
22
|
+
ba = new JsonBloomfilter.BitArray(10);
|
23
|
+
ba.add(9);
|
24
|
+
expect(ba.toString()).toBe("0000000001");
|
25
|
+
});
|
26
|
+
|
27
|
+
it("should throw an error on out of bound", function() {
|
28
|
+
ba = new JsonBloomfilter.BitArray(10);
|
29
|
+
ba.add(9);
|
30
|
+
expect(function(){ba.add(10);}).toThrow("BitArray index out of bounds");
|
31
|
+
});
|
32
|
+
});
|
33
|
+
|
34
|
+
describe("#remove", function() {
|
35
|
+
it("should set the bit to 0", function() {
|
36
|
+
ba = new JsonBloomfilter.BitArray(10);
|
37
|
+
ba.add(9);
|
38
|
+
ba.remove(9);
|
39
|
+
expect(ba.toString()).toBe("0000000000");
|
40
|
+
});
|
41
|
+
|
42
|
+
it("should throw an error on out of bound", function() {
|
43
|
+
ba = new JsonBloomfilter.BitArray(10);
|
44
|
+
expect(function(){ba.remove(10);}).toThrow("BitArray index out of bounds");
|
45
|
+
});
|
46
|
+
});
|
47
|
+
|
48
|
+
describe("#get", function() {
|
49
|
+
it("should return the bit set", function() {
|
50
|
+
ba = new JsonBloomfilter.BitArray(10);
|
51
|
+
ba.add(9);
|
52
|
+
expect(ba.get(9)).toBe(1);
|
53
|
+
expect(ba.get(8)).toBe(0);
|
54
|
+
});
|
55
|
+
|
56
|
+
it("should throw an error on out of bound", function() {
|
57
|
+
ba = new JsonBloomfilter.BitArray(10);
|
58
|
+
expect(function(){ba.get(10);}).toThrow("BitArray index out of bounds");
|
59
|
+
});
|
60
|
+
});
|
61
|
+
|
62
|
+
describe("#toString", function() {
|
63
|
+
it("should output the bit string", function() {
|
64
|
+
ba = new JsonBloomfilter.BitArray(10);
|
65
|
+
ba.add(3);
|
66
|
+
ba.add(9);
|
67
|
+
expect(ba.toString()).toBe("0001000001");
|
68
|
+
});
|
69
|
+
});
|
70
|
+
});
|
@@ -0,0 +1,75 @@
|
|
1
|
+
describe("JsonBloomfilter", function() {
|
2
|
+
|
3
|
+
describe("#initialize", function() {
|
4
|
+
it("should take the appropriate options", function() {
|
5
|
+
seed = (new Date().getTime()/1000) - 24*60*60;
|
6
|
+
bf = new JsonBloomfilter({ size: 200, hashes: 10, seed: seed });
|
7
|
+
expect(bf.toHash()["size"]).toBe(200);
|
8
|
+
expect(bf.toHash()["hashes"]).toBe(10);
|
9
|
+
expect(bf.toHash()["seed"]).toBe(seed);
|
10
|
+
});
|
11
|
+
|
12
|
+
it("should be initializable with a field serialized by another bloom filter", function() {
|
13
|
+
bf1 = new JsonBloomfilter();
|
14
|
+
bf1.add("foo");
|
15
|
+
bf2 = new JsonBloomfilter(bf1.toHash());
|
16
|
+
expect(bf2.test("foo")).toBe(true);
|
17
|
+
});
|
18
|
+
|
19
|
+
it("should initialize the field with the right size", function() {
|
20
|
+
bf = new JsonBloomfilter({size: 100});
|
21
|
+
expect(bf.toHash()["bits"].length).toBe(4);
|
22
|
+
});
|
23
|
+
});
|
24
|
+
|
25
|
+
describe("with an instance", function() {
|
26
|
+
var bf;
|
27
|
+
|
28
|
+
beforeEach(function() {
|
29
|
+
bf = new JsonBloomfilter();
|
30
|
+
bf.add("foobar");
|
31
|
+
});
|
32
|
+
|
33
|
+
describe("#add, #test", function() {
|
34
|
+
it("should add a key", function() {
|
35
|
+
expect(bf.test("foo")).toBe(false);
|
36
|
+
bf.add("foo");
|
37
|
+
expect(bf.test("foo")).toBe(true);
|
38
|
+
});
|
39
|
+
|
40
|
+
it("should not change anything if added twice", function() {
|
41
|
+
expect(bf.test("foobar")).toBe(true);
|
42
|
+
bits = bf.toHash()["bits"];
|
43
|
+
bf.add("foobar");
|
44
|
+
expect(bf.test("foobar")).toBe(true);
|
45
|
+
expect(bf.toHash()["bits"]).toBe(bits);
|
46
|
+
});
|
47
|
+
});
|
48
|
+
|
49
|
+
describe("#clear", function() {
|
50
|
+
it("should clear the bit array", function() {
|
51
|
+
expect(bf.bits.toString()).not.toBe("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
52
|
+
bf.clear();
|
53
|
+
expect(bf.bits.toString()).toBe("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
54
|
+
});
|
55
|
+
});
|
56
|
+
|
57
|
+
describe("#toHash", function() {
|
58
|
+
it("should return the serialisable hash", function() {
|
59
|
+
hash = bf.toHash();
|
60
|
+
expect(hash instanceof Object).toBe(true);
|
61
|
+
expect(hash["seed"]).not.toBeUndefined();
|
62
|
+
expect(hash["hashes"]).not.toBeUndefined();
|
63
|
+
expect(hash["size"]).not.toBeUndefined();
|
64
|
+
expect(hash["bits"]).not.toBeUndefined();
|
65
|
+
});
|
66
|
+
});
|
67
|
+
|
68
|
+
describe("#toJson", function() {
|
69
|
+
it("should return the hash serialised", function() {
|
70
|
+
expect(bf.toJson()).toBe(JSON.stringify(bf.toHash()));
|
71
|
+
});
|
72
|
+
});
|
73
|
+
|
74
|
+
});
|
75
|
+
});
|
@@ -0,0 +1,10 @@
|
|
1
|
+
describe("JsonBloomfilter.Zlib", function() {
|
2
|
+
|
3
|
+
describe("#crc32", function() {
|
4
|
+
it("should hash the input correctly", function() {
|
5
|
+
expect(JsonBloomfilter.Zlib.crc32("foobar")).toBe(2666930069);
|
6
|
+
expect(JsonBloomfilter.Zlib.crc32("Magna Pellentesque Egestas Nibh Ultricies")).toBe(1920919084);
|
7
|
+
});
|
8
|
+
|
9
|
+
});
|
10
|
+
});
|
@@ -14,7 +14,7 @@ describe JsonBloomfilter::BitArray do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
describe "add" do
|
17
|
+
describe "#add" do
|
18
18
|
it "should set the bit to 1" do
|
19
19
|
ba = JsonBloomfilter::BitArray.new(10)
|
20
20
|
ba.add(9)
|
@@ -27,7 +27,7 @@ describe JsonBloomfilter::BitArray do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
describe "remove" do
|
30
|
+
describe "#remove" do
|
31
31
|
it "should set the bit to 0" do
|
32
32
|
ba = JsonBloomfilter::BitArray.new(10)
|
33
33
|
ba.add(9)
|
@@ -41,7 +41,7 @@ describe JsonBloomfilter::BitArray do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
describe "get" do
|
44
|
+
describe "#get" do
|
45
45
|
it "should return the bit set" do
|
46
46
|
ba = JsonBloomfilter::BitArray.new(10)
|
47
47
|
ba.add(9)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json-bloomfilter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -107,6 +107,22 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: jasmine
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
110
126
|
description: A bloomfilter implementation in both Ruby and Javascript that can be
|
111
127
|
serialised to and loaded from JSON. Very useful when needing to train a bloom filter
|
112
128
|
in one language and using it in the other.
|
@@ -133,6 +149,11 @@ files:
|
|
133
149
|
- lib/json/bloomfilter/version.rb
|
134
150
|
- pkg/json-bloomfilter-0.0.1.gem
|
135
151
|
- pkg/json-bloomfilter-0.0.2.gem
|
152
|
+
- pkg/json-bloomfilter-0.0.3.gem
|
153
|
+
- spec/javascripts/bitarray_spec.js
|
154
|
+
- spec/javascripts/bloomfilter_spec.js
|
155
|
+
- spec/javascripts/support/jasmine.yml
|
156
|
+
- spec/javascripts/zlib_spec.js
|
136
157
|
- spec/json/bloomfilter/bitarray_spec.rb
|
137
158
|
- spec/json/bloomfilter_spec.rb
|
138
159
|
- spec/spec_helper.rb
|
@@ -157,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
178
|
version: '0'
|
158
179
|
segments:
|
159
180
|
- 0
|
160
|
-
hash:
|
181
|
+
hash: -4107655990555845610
|
161
182
|
requirements: []
|
162
183
|
rubyforge_project:
|
163
184
|
rubygems_version: 1.8.24
|
@@ -165,6 +186,10 @@ signing_key:
|
|
165
186
|
specification_version: 3
|
166
187
|
summary: A bloomfilter implementation in both Ruby and Javascript.
|
167
188
|
test_files:
|
189
|
+
- spec/javascripts/bitarray_spec.js
|
190
|
+
- spec/javascripts/bloomfilter_spec.js
|
191
|
+
- spec/javascripts/support/jasmine.yml
|
192
|
+
- spec/javascripts/zlib_spec.js
|
168
193
|
- spec/json/bloomfilter/bitarray_spec.rb
|
169
194
|
- spec/json/bloomfilter_spec.rb
|
170
195
|
- spec/spec_helper.rb
|