bitarray 0.0.1
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +23 -0
- data/Rakefile +5 -0
- data/bitarray.gemspec +19 -0
- data/lib/bitarray.rb +41 -0
- data/test/test_bitarray.rb +62 -0
- metadata +54 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# BitArray: A simple bit array/bit field library in pure Ruby
|
2
|
+
|
3
|
+
Basic, pure Ruby bit field. Pretty fast (for what it is) and memory efficient. Works well for Bloom filters (the reason I wrote it).
|
4
|
+
|
5
|
+
Written in 2007 and not updated since then, just bringing it on to GitHub by user request. It used to be called Bitfield and was hosted at http://snippets.dzone.com/posts/show/4234
|
6
|
+
|
7
|
+
## Examples
|
8
|
+
|
9
|
+
Create a bit field 1000 bits wide
|
10
|
+
bf = BitField.new(1000)
|
11
|
+
|
12
|
+
Setting and reading bits
|
13
|
+
bf[100] = 1
|
14
|
+
bf[100] .. => 1
|
15
|
+
bf[100] = 0
|
16
|
+
|
17
|
+
More
|
18
|
+
bf.to_s = "10101000101010101" (example)
|
19
|
+
bf.total_set .. => 10 (example - 10 bits are set to "1")
|
20
|
+
|
21
|
+
## License
|
22
|
+
|
23
|
+
MIT licensed. Copyright 2007-2012 Peter Cooper, yada yada.
|
data/Rakefile
ADDED
data/bitarray.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "bitarray"
|
6
|
+
s.version = "0.0.1"
|
7
|
+
s.authors = ["Peter Cooper"]
|
8
|
+
s.email = ["git@peterc.org"]
|
9
|
+
s.homepage = "https://github.com/peterc/bitarray"
|
10
|
+
s.summary = %q{A simple, pure Ruby bit array implementation.}
|
11
|
+
s.description = %q{A simple, pure Ruby bit array implementation.}
|
12
|
+
|
13
|
+
s.rubyforge_project = "bitarray"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
end
|
data/lib/bitarray.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
class BitArray
|
2
|
+
attr_reader :size
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
ELEMENT_WIDTH = 32
|
6
|
+
|
7
|
+
def initialize(size)
|
8
|
+
@size = size
|
9
|
+
@field = Array.new(((size - 1) / ELEMENT_WIDTH) + 1, 0)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Set a bit (1/0)
|
13
|
+
def []=(position, value)
|
14
|
+
if value == 1
|
15
|
+
@field[position / ELEMENT_WIDTH] |= 1 << (position % ELEMENT_WIDTH)
|
16
|
+
elsif (@field[position / ELEMENT_WIDTH]) & (1 << (position % ELEMENT_WIDTH)) != 0
|
17
|
+
@field[position / ELEMENT_WIDTH] ^= 1 << (position % ELEMENT_WIDTH)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Read a bit (1/0)
|
22
|
+
def [](position)
|
23
|
+
@field[position / ELEMENT_WIDTH] & 1 << (position % ELEMENT_WIDTH) > 0 ? 1 : 0
|
24
|
+
end
|
25
|
+
|
26
|
+
# Iterate over each bit
|
27
|
+
def each(&block)
|
28
|
+
@size.times { |position| yield self[position] }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the field as a string like "0101010100111100," etc.
|
32
|
+
def to_s
|
33
|
+
inject("") { |a, b| a + b.to_s }
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the total number of bits that are set
|
37
|
+
# (The technique used here is about 6 times faster than using each or inject direct on the bitfield)
|
38
|
+
def total_set
|
39
|
+
@field.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a }
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "bitarray"
|
3
|
+
|
4
|
+
class TestBitArray < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@public_bf = BitArray.new(1000)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_basic
|
10
|
+
assert_equal 0, BitArray.new(100)[0]
|
11
|
+
assert_equal 0, BitArray.new(100)[1]
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_setting_and_unsetting
|
15
|
+
@public_bf[100] = 1
|
16
|
+
assert_equal 1, @public_bf[100]
|
17
|
+
@public_bf[100] = 0
|
18
|
+
assert_equal 0, @public_bf[100]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_random_setting_and_unsetting
|
22
|
+
100.times do
|
23
|
+
index = rand(1000)
|
24
|
+
@public_bf[index] = 1
|
25
|
+
assert_equal 1, @public_bf[index]
|
26
|
+
@public_bf[index] = 0
|
27
|
+
assert_equal 0, @public_bf[index]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_multiple_setting
|
32
|
+
1.upto(999) do |pos|
|
33
|
+
2.times { @public_bf[pos] = 1 }
|
34
|
+
assert_equal 1, @public_bf[pos]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_multiple_unsetting
|
39
|
+
1.upto(999) do |pos|
|
40
|
+
2.times { @public_bf[pos] = 0 }
|
41
|
+
assert_equal 0, @public_bf[pos]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_size
|
46
|
+
assert_equal 1000, @public_bf.size
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_to_s
|
50
|
+
bf = BitArray.new(10)
|
51
|
+
bf[1] = 1
|
52
|
+
bf[5] = 1
|
53
|
+
assert_equal "0100010000", bf.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_total_set
|
57
|
+
bf = BitArray.new(10)
|
58
|
+
bf[1] = 1
|
59
|
+
bf[5] = 1
|
60
|
+
assert_equal 2, bf.total_set
|
61
|
+
end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bitarray
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Peter Cooper
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-18 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A simple, pure Ruby bit array implementation.
|
15
|
+
email:
|
16
|
+
- git@peterc.org
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- README.md
|
24
|
+
- Rakefile
|
25
|
+
- bitarray.gemspec
|
26
|
+
- lib/bitarray.rb
|
27
|
+
- test/test_bitarray.rb
|
28
|
+
homepage: https://github.com/peterc/bitarray
|
29
|
+
licenses: []
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project: bitarray
|
48
|
+
rubygems_version: 1.8.10
|
49
|
+
signing_key:
|
50
|
+
specification_version: 3
|
51
|
+
summary: A simple, pure Ruby bit array implementation.
|
52
|
+
test_files:
|
53
|
+
- test/test_bitarray.rb
|
54
|
+
has_rdoc:
|