bitwise 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +21 -12
- data/VERSION +1 -1
- data/bitwise.gemspec +2 -3
- data/lib/bitwise.rb +25 -16
- data/spec/bitwise_spec.rb +29 -18
- metadata +10 -11
- data/.document +0 -5
data/README.md
CHANGED
@@ -3,7 +3,7 @@ Bitwise
|
|
3
3
|
|
4
4
|
Fast, memory efficient bitwise operations on large binary strings.
|
5
5
|
|
6
|
-
Internally a bit array is represented as a ruby string with `Encoding::
|
6
|
+
Internally a bit array is represented as a ruby string with `Encoding::BINARY` encoding, which keeps billions of bits in a workable footprint.
|
7
7
|
|
8
8
|
* 1,000,000 bits = 125KB
|
9
9
|
* 10,000,000 bits = 1.25MB
|
@@ -18,47 +18,47 @@ Install
|
|
18
18
|
Usage
|
19
19
|
-----
|
20
20
|
|
21
|
-
|
21
|
+
Set and clear bits:
|
22
22
|
|
23
23
|
```ruby
|
24
24
|
b = Bitwise.new("\x00")
|
25
25
|
|
26
|
-
b.
|
26
|
+
b.bits
|
27
27
|
=> "00000000"
|
28
28
|
|
29
29
|
b.set_at(1)
|
30
30
|
b.set_at(4)
|
31
31
|
|
32
|
-
b.
|
32
|
+
b.bits
|
33
33
|
=> "01001000"
|
34
34
|
|
35
35
|
b.clear_at(1)
|
36
36
|
|
37
|
-
b.
|
37
|
+
b.bits
|
38
38
|
=> "00001000"
|
39
39
|
```
|
40
40
|
|
41
|
-
String-based
|
41
|
+
String-based accessor:
|
42
42
|
|
43
43
|
```ruby
|
44
44
|
b = Bitwise.new
|
45
|
-
b.
|
45
|
+
b.raw = "abc"
|
46
46
|
|
47
47
|
b.size
|
48
48
|
=> 3
|
49
|
-
b.
|
49
|
+
b.bits
|
50
50
|
=> "011000010110001001100011"
|
51
|
-
b.
|
51
|
+
b.raw.unpack('C*')
|
52
52
|
=> [97, 98, 99]
|
53
53
|
```
|
54
54
|
|
55
|
-
Index-based
|
55
|
+
Index-based accessor:
|
56
56
|
|
57
57
|
```ruby
|
58
58
|
b = Bitwise.new
|
59
59
|
b.indexes = [1, 2, 4, 8, 16]
|
60
60
|
|
61
|
-
b.
|
61
|
+
b.bits
|
62
62
|
=> "011010001000000010000000"
|
63
63
|
b.indexes
|
64
64
|
=> [1, 2, 4, 8, 16]
|
@@ -67,7 +67,7 @@ b.cardinality
|
|
67
67
|
|
68
68
|
b.set_at(10)
|
69
69
|
|
70
|
-
b.
|
70
|
+
b.bits
|
71
71
|
=> "011010001010000010000000"
|
72
72
|
b.indexes
|
73
73
|
=> [1, 2, 4, 8, 10, 16]
|
@@ -75,6 +75,15 @@ b.cardinality
|
|
75
75
|
=> 6
|
76
76
|
```
|
77
77
|
|
78
|
+
Bit-based accessor is also provided for convenience, but be aware that it's not efficient. Use string-based accessor whenever possible.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
b = Bitwise.new
|
82
|
+
b.bits = '0100100010'
|
83
|
+
b.bits
|
84
|
+
=> "0100100010000000"
|
85
|
+
```
|
86
|
+
|
78
87
|
NOT, OR, AND and XOR:
|
79
88
|
|
80
89
|
```ruby
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/bitwise.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "bitwise"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kenn Ejima"]
|
12
|
-
s.date = "2011-12-
|
12
|
+
s.date = "2011-12-17"
|
13
13
|
s.description = "Fast, memory efficient bitwise operations on large binary strings"
|
14
14
|
s.email = "kenn.ejima@gmail.com"
|
15
15
|
s.extensions = ["ext/bitwise/extconf.rb"]
|
@@ -18,7 +18,6 @@ Gem::Specification.new do |s|
|
|
18
18
|
"README.md"
|
19
19
|
]
|
20
20
|
s.files = [
|
21
|
-
".document",
|
22
21
|
"Gemfile",
|
23
22
|
"LICENSE.txt",
|
24
23
|
"README.md",
|
data/lib/bitwise.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# encoding: binary
|
2
2
|
|
3
3
|
require 'bitwise/bitwise'
|
4
4
|
|
5
5
|
class Bitwise
|
6
6
|
attr_accessor :value
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
|
8
|
+
def initialize(string = "")
|
9
|
+
self.raw = string
|
10
10
|
end
|
11
11
|
|
12
12
|
def size
|
@@ -14,10 +14,6 @@ class Bitwise
|
|
14
14
|
end
|
15
15
|
alias :to_s :size
|
16
16
|
|
17
|
-
def to_bits
|
18
|
-
@value.unpack('B*').first
|
19
|
-
end
|
20
|
-
|
21
17
|
def set_at(index)
|
22
18
|
get_byte(index)
|
23
19
|
@value.setbyte(@div, @byte | bitmask)
|
@@ -52,7 +48,7 @@ class Bitwise
|
|
52
48
|
end
|
53
49
|
|
54
50
|
def not
|
55
|
-
Bitwise.new(Bitwise.string_not(self.
|
51
|
+
Bitwise.new(Bitwise.string_not(self.raw))
|
56
52
|
end
|
57
53
|
alias :~ :not
|
58
54
|
|
@@ -75,11 +71,26 @@ class Bitwise
|
|
75
71
|
alias :^ :xor
|
76
72
|
|
77
73
|
def assign_max_and_min(other)
|
78
|
-
@min, @max = [ self.
|
74
|
+
@min, @max = [ self.raw, other.raw ].sort_by{|i| i.bytesize }
|
75
|
+
end
|
76
|
+
|
77
|
+
def bits
|
78
|
+
@value.unpack('B*').first
|
79
79
|
end
|
80
80
|
|
81
|
-
def
|
82
|
-
@value = string.
|
81
|
+
def bits=(string)
|
82
|
+
@value = string.scan(/[01]{1,8}/).map do |slice|
|
83
|
+
(slice.bytesize == 8 ? slice : (slice + '0' * (8 - slice.bytesize))).to_i(2).chr
|
84
|
+
end.join
|
85
|
+
@value.bytesize
|
86
|
+
end
|
87
|
+
|
88
|
+
def raw
|
89
|
+
@value
|
90
|
+
end
|
91
|
+
|
92
|
+
def raw=(string)
|
93
|
+
@value = string.force_encoding(Encoding::BINARY)
|
83
94
|
@value.bytesize
|
84
95
|
end
|
85
96
|
|
@@ -89,23 +100,21 @@ class Bitwise
|
|
89
100
|
array.each do |index|
|
90
101
|
set_at(index)
|
91
102
|
end
|
92
|
-
|
103
|
+
@value.bytesize
|
93
104
|
end
|
94
105
|
|
95
106
|
def indexes
|
96
107
|
indexes = []
|
97
|
-
|
98
|
-
@value.each_byte do |c|
|
108
|
+
@value.each_byte.with_index do |c, position|
|
99
109
|
BITS_TABLE[c].each do |i|
|
100
110
|
indexes << (position*8 + i)
|
101
111
|
end
|
102
|
-
position += 1
|
103
112
|
end
|
104
113
|
indexes
|
105
114
|
end
|
106
115
|
|
107
116
|
def cardinality
|
108
|
-
Bitwise.population_count(self.
|
117
|
+
Bitwise.population_count(self.raw)
|
109
118
|
end
|
110
119
|
|
111
120
|
BITS_TABLE = (0..255).map do |i|
|
data/spec/bitwise_spec.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# coding: ascii-8bit
|
2
|
-
|
3
1
|
require 'bitwise'
|
4
2
|
require 'set'
|
5
3
|
|
@@ -8,38 +6,51 @@ describe Bitwise do
|
|
8
6
|
@bitwise = Bitwise.new("\x00")
|
9
7
|
end
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
it "should encode to binary" do
|
10
|
+
@bitwise.raw.encoding.should == Encoding::BINARY
|
11
|
+
@bitwise.indexes = [1,2]
|
12
|
+
@bitwise.raw.encoding.should == Encoding::BINARY
|
13
|
+
end
|
14
|
+
|
15
|
+
it "set and clear" do
|
16
|
+
@bitwise.bits.should == '00000000'
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
@bitwise.set_at(1)
|
19
|
+
@bitwise.set_at(4)
|
20
|
+
@bitwise.bits.should == '01001000'
|
21
|
+
@bitwise.cardinality.should == 2
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
@bitwise.clear_at(1)
|
24
|
+
@bitwise.bits.should == '00001000'
|
25
|
+
@bitwise.cardinality.should == 1
|
23
26
|
|
24
|
-
|
25
|
-
|
27
|
+
lambda { @bitwise.set_at(7) }.should_not raise_error(IndexError)
|
28
|
+
lambda { @bitwise.set_at(8) }.should raise_error(IndexError)
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "accessor" do
|
32
|
+
it "bit-based" do
|
33
|
+
@bitwise.bits = '0100100010'
|
34
|
+
@bitwise.size.should == 2
|
35
|
+
@bitwise.bits.should == '0100100010000000'
|
36
|
+
@bitwise.cardinality.should == 3
|
26
37
|
end
|
27
38
|
|
28
39
|
it "string-based" do
|
29
|
-
@bitwise.
|
40
|
+
@bitwise.raw = 'abc'
|
30
41
|
@bitwise.size.should == 3
|
31
|
-
@bitwise.
|
42
|
+
@bitwise.bits.should == '011000010110001001100011'
|
32
43
|
@bitwise.cardinality.should == 10
|
33
44
|
end
|
34
45
|
|
35
46
|
it "index-based" do
|
36
47
|
@bitwise.indexes = [1, 2, 4, 8, 16]
|
37
|
-
@bitwise.
|
48
|
+
@bitwise.bits.should == '011010001000000010000000'
|
38
49
|
@bitwise.indexes.should == [1, 2, 4, 8, 16]
|
39
50
|
@bitwise.cardinality.should == 5
|
40
51
|
|
41
52
|
@bitwise.set_at 10
|
42
|
-
@bitwise.
|
53
|
+
@bitwise.bits.should == '011010001010000010000000'
|
43
54
|
@bitwise.indexes.should == [1, 2, 4, 8, 10, 16]
|
44
55
|
@bitwise.cardinality.should == 6
|
45
56
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitwise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153110060 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153110060
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bundler
|
27
|
-
requirement: &
|
27
|
+
requirement: &2153109020 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153109020
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jeweler
|
38
|
-
requirement: &
|
38
|
+
requirement: &2153108300 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2153108300
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake-compiler
|
49
|
-
requirement: &
|
49
|
+
requirement: &2153107500 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2153107500
|
58
58
|
description: Fast, memory efficient bitwise operations on large binary strings
|
59
59
|
email: kenn.ejima@gmail.com
|
60
60
|
executables: []
|
@@ -64,7 +64,6 @@ extra_rdoc_files:
|
|
64
64
|
- LICENSE.txt
|
65
65
|
- README.md
|
66
66
|
files:
|
67
|
-
- .document
|
68
67
|
- Gemfile
|
69
68
|
- LICENSE.txt
|
70
69
|
- README.md
|