ingramj-bitarray 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.o
2
+ *.so
3
+ Makefile
4
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2009 James E. Ingram
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
data/README ADDED
@@ -0,0 +1,28 @@
1
+ A bit array class for Ruby, implemented as a C extension. Includes methods for
2
+ setting and clearing individual bits, and all bits at once. Also has the
3
+ standard array access methods, [] and []=, and it mixes in Enumerable.
4
+
5
+ The test/ directory has a unit test file. It also has a benchmark utility for
6
+ comparison with Peter Cooper's pure Ruby BitField class.
7
+
8
+ This extension has only been tested with Ruby 1.9.1 on Ubuntu, and probably
9
+ won't compile for Ruby 1.8. Compatibility with Ruby 1.8 is planned.
10
+
11
+ This library is available as a gem. Install it with
12
+
13
+ sudo gem install ingramj-bitarray -s http://gems.github.com
14
+
15
+ Alternately, you can clone the repository and build things manually.
16
+
17
+ See the TODO file for current limitations and plans.
18
+
19
+ See the LICENSE file for copyright and license information.
20
+
21
+ Some inspiration was taken from Peter Cooper's BitField class, and various Open
22
+ Source bitarray implementations found online, but this implementation contains
23
+ only original code, except for test/bitfield.rb, which is Peter Cooper's
24
+ BitField class, and test/test.rb, which was modified from the BitField test
25
+ code.
26
+
27
+ BitField: http://snippets.dzone.com/posts/show/4234
28
+
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "bitarray"
5
+ gem.summary = "A bitarray class for Ruby, implemented as a C extension."
6
+ gem.description = <<EOF
7
+ A bit array class for Ruby, implemented as a C extension. Includes methods for
8
+ setting and clearing individual bits, and all bits at once. Also has the
9
+ standard array access methods, [] and []=, and it mixes in Enumerable.
10
+ EOF
11
+ gem.email = "ingramj@gmail.com"
12
+ gem.homepage = "http://github.com/ingramj/bitarray"
13
+ gem.authors = ["James E. Ingram"]
14
+ gem.require_paths = ["ext"]
15
+ gem.extensions = ["ext/extconf.rb"]
16
+ gem.required_ruby_version = ">= 1.9.1"
17
+ gem.rdoc_options << '--exclude' << 'ext/Makefile' << '--title' << ' BitArray Documentation'
18
+ end
19
+ rescue LoadError
20
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
21
+ end
22
+
data/TODO ADDED
@@ -0,0 +1,9 @@
1
+ * Comment code. I'd like for it to be useful as a tutorial for extension
2
+ writing, especially with regards to implementing new types.
3
+ * Implement some more methods, like Hamming weight, and slice, and in-place
4
+ enumerator methods (map!, reverse!, etc).
5
+ * Maybe allow resizing.
6
+ * Write more tests
7
+ * Ruby 1.8 compatibility. This will probably involve just changing some of the
8
+ NUM2x and x2NUM defines.
9
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bitarray.gemspec ADDED
@@ -0,0 +1,53 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{bitarray}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["James E. Ingram"]
9
+ s.date = %q{2009-05-23}
10
+ s.description = %q{A bit array class for Ruby, implemented as a C extension. Includes methods for setting and clearing individual bits, and all bits at once. Also has the standard array access methods, [] and []=, and it mixes in Enumerable.}
11
+ s.email = %q{ingramj@gmail.com}
12
+ s.extensions = ["ext/extconf.rb"]
13
+ s.extra_rdoc_files = [
14
+ "LICENSE",
15
+ "README"
16
+ ]
17
+ s.files = [
18
+ ".gitignore",
19
+ "LICENSE",
20
+ "README",
21
+ "Rakefile",
22
+ "TODO",
23
+ "VERSION",
24
+ "bitarray.gemspec",
25
+ "ext/bitarray.c",
26
+ "ext/extconf.rb",
27
+ "test/bitfield.rb",
28
+ "test/bm.rb",
29
+ "test/test.rb"
30
+ ]
31
+ s.has_rdoc = true
32
+ s.homepage = %q{http://github.com/ingramj/bitarray}
33
+ s.rdoc_options = ["--charset=UTF-8", "--exclude", "ext/Makefile", "--title", " BitArray Documentation"]
34
+ s.require_paths = ["ext"]
35
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.1")
36
+ s.rubygems_version = %q{1.3.1}
37
+ s.summary = %q{A bitarray class for Ruby, implemented as a C extension.}
38
+ s.test_files = [
39
+ "test/bitfield.rb",
40
+ "test/test.rb",
41
+ "test/bm.rb"
42
+ ]
43
+
44
+ if s.respond_to? :specification_version then
45
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
+ s.specification_version = 2
47
+
48
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
49
+ else
50
+ end
51
+ else
52
+ end
53
+ end
data/ext/bitarray.c ADDED
@@ -0,0 +1,347 @@
1
+ #include "ruby.h"
2
+ #include <limits.h>
3
+ #include <string.h>
4
+
5
+ /* Bits are stored in an array of unsigned ints. We'll use a couple of defines
6
+ * for getting the size of unsigned ints in bytes and bits.
7
+ */
8
+ #define UINT_BYTES (sizeof(unsigned int))
9
+ #define UINT_BITS (UINT_BYTES * CHAR_BIT)
10
+
11
+ /* bitmask macro for accessing a particular bit inside an array element. */
12
+ #define bitmask(bit) (1 << (bit % UINT_BITS))
13
+
14
+ /* Bit Array structure. */
15
+ struct bit_array {
16
+ size_t bits; /* Number of bits. */
17
+ size_t array_size; /* Size of the storage array. */
18
+ unsigned int *array; /* Array of unsigned ints, used for bit storage. */
19
+ };
20
+
21
+
22
+ /* Bit Array manipulation functions. */
23
+
24
+ /* Set the specified bit to 1. Return 1 on success, 0 on failure. */
25
+ static int
26
+ set_bit(struct bit_array *ba, ptrdiff_t bit)
27
+ {
28
+ if (bit < 0) bit += ba->bits;
29
+ if (bit >= ba->bits) {
30
+ return 0;
31
+ }
32
+
33
+ ba->array[bit / UINT_BITS] |= bitmask(bit);
34
+ return 1;
35
+ }
36
+
37
+
38
+ /* Set all bits to 1. */
39
+ static int
40
+ set_all_bits(struct bit_array *ba)
41
+ {
42
+ memset(ba->array, 0xff, (ba->array_size * UINT_BYTES));
43
+ return 1;
44
+ }
45
+
46
+
47
+ /* Clear the specified bit to 0. Return 1 on success, 0 on failure. */
48
+ static int
49
+ clear_bit(struct bit_array *ba, ptrdiff_t bit)
50
+ {
51
+ if (bit < 0) bit += ba->bits;
52
+ if (bit >= ba->bits) {
53
+ return 0;
54
+ }
55
+
56
+ ba->array[bit / UINT_BITS] &= ~bitmask(bit);
57
+ return 1;
58
+ }
59
+
60
+
61
+ /* Clear all bits to 0. */
62
+ static int
63
+ clear_all_bits(struct bit_array *ba)
64
+ {
65
+ memset(ba->array, 0x00, (ba->array_size * UINT_BYTES));
66
+ return 1;
67
+ }
68
+
69
+
70
+ /* Toggle the state of the specified bit. Return 1 on success, 0 on failure. */
71
+ static int
72
+ toggle_bit(struct bit_array *ba, ptrdiff_t bit)
73
+ {
74
+ if (bit < 0) bit += ba->bits;
75
+ if (bit >= ba->bits) {
76
+ return 0;
77
+ }
78
+
79
+ ba->array[bit / UINT_BITS] ^= bitmask(bit);
80
+ return 1;
81
+ }
82
+
83
+
84
+ /* Assign the specified value to a bit. Return 1 on success, 0 on invalid bit
85
+ * index, and -1 on invalid value. */
86
+ static int
87
+ assign_bit(struct bit_array *ba, ptrdiff_t bit, int value)
88
+ {
89
+ if (value == 0) {
90
+ return clear_bit(ba, bit);
91
+ } else if (value == 1) {
92
+ return set_bit(ba, bit);
93
+ } else {
94
+ return -1;
95
+ }
96
+ }
97
+
98
+
99
+ /* Get the state of the specified bit. Return -1 on failure. */
100
+ static int
101
+ get_bit(struct bit_array *ba, ptrdiff_t bit)
102
+ {
103
+ if (bit < 0) bit += ba->bits;
104
+ if (bit >= ba->bits) {
105
+ return -1;
106
+ }
107
+
108
+ unsigned int b = (ba->array[bit / UINT_BITS] & bitmask(bit));
109
+ if (b > 0) {
110
+ return 1;
111
+ } else {
112
+ return 0;
113
+ }
114
+ }
115
+
116
+
117
+ /* Ruby Interface Functions. These aren't documented yet. */
118
+
119
+ static VALUE rb_bitarray_class;
120
+
121
+
122
+ static void
123
+ rb_bitarray_free(struct bit_array *ba)
124
+ {
125
+ if (ba && ba->array) {
126
+ ruby_xfree(ba->array);
127
+ }
128
+ ruby_xfree(ba);
129
+ }
130
+
131
+
132
+ static VALUE
133
+ rb_bitarray_alloc(VALUE klass)
134
+ {
135
+ struct bit_array *ba;
136
+ return Data_Make_Struct(rb_bitarray_class, struct bit_array, NULL,
137
+ rb_bitarray_free, ba);
138
+ }
139
+
140
+
141
+ static VALUE
142
+ rb_bitarray_initialize(VALUE self, VALUE size)
143
+ {
144
+ struct bit_array *ba;
145
+ Data_Get_Struct(self, struct bit_array, ba);
146
+
147
+ size_t bits = NUM2SIZET(size);
148
+ size_t array_size = ((bits - 1) / UINT_BITS) + 1;
149
+
150
+ ba->bits = bits;
151
+ ba->array_size = array_size;
152
+ ba->array = ruby_xcalloc(array_size, UINT_BYTES);
153
+
154
+ return self;
155
+ }
156
+
157
+
158
+ static VALUE
159
+ rb_bitarray_clone(VALUE self)
160
+ {
161
+ struct bit_array *ba, *new_ba;
162
+ VALUE rb_new_ba;
163
+ Data_Get_Struct(self, struct bit_array, ba);
164
+ rb_new_ba = Data_Make_Struct(rb_bitarray_class, struct bit_array, NULL,
165
+ rb_bitarray_free, new_ba);
166
+
167
+ new_ba->bits = ba->bits;
168
+ new_ba->array_size = ba->array_size;
169
+ new_ba->array = ruby_xcalloc(new_ba->array_size, UINT_BYTES);
170
+
171
+ memcpy(new_ba->array, ba->array, (ba->array_size * UINT_BYTES));
172
+
173
+ return rb_new_ba;
174
+ }
175
+
176
+
177
+ static VALUE
178
+ rb_bitarray_size(VALUE self)
179
+ {
180
+ struct bit_array *ba;
181
+ Data_Get_Struct(self, struct bit_array, ba);
182
+
183
+ return SIZET2NUM(ba->bits);
184
+ }
185
+
186
+
187
+ static VALUE
188
+ rb_bitarray_set_bit(VALUE self, VALUE bit)
189
+ {
190
+ struct bit_array *ba;
191
+ Data_Get_Struct(self, struct bit_array, ba);
192
+
193
+ ptrdiff_t index = NUM2SSIZET(bit);
194
+
195
+ if (set_bit(ba, index)) {
196
+ return self;
197
+ } else {
198
+ rb_raise(rb_eIndexError, "index %ld out of bit array", (long)index);
199
+ }
200
+ }
201
+
202
+
203
+ static VALUE
204
+ rb_bitarray_set_all_bits(VALUE self)
205
+ {
206
+ struct bit_array *ba;
207
+ Data_Get_Struct(self, struct bit_array, ba);
208
+
209
+ if(set_all_bits(ba)) {
210
+ return self;
211
+ } else {
212
+ rb_bug("BitArray#set_all_bits failed. This should not occur.");
213
+ }
214
+ }
215
+
216
+
217
+ static VALUE
218
+ rb_bitarray_clear_bit(VALUE self, VALUE bit)
219
+ {
220
+ struct bit_array *ba;
221
+ Data_Get_Struct(self, struct bit_array, ba);
222
+
223
+ ptrdiff_t index = NUM2SSIZET(bit);
224
+
225
+ if (clear_bit(ba, index)) {
226
+ return self;
227
+ } else {
228
+ rb_raise(rb_eIndexError, "index %ld out of bit array", (long)index);
229
+ }
230
+ }
231
+
232
+
233
+ static VALUE
234
+ rb_bitarray_clear_all_bits(VALUE self)
235
+ {
236
+ struct bit_array *ba;
237
+ Data_Get_Struct(self, struct bit_array, ba);
238
+
239
+ if(clear_all_bits(ba)) {
240
+ return self;
241
+ } else {
242
+ rb_bug("BitArray#clear_all_bits failed. This should not occur.");
243
+ }
244
+ }
245
+
246
+
247
+ static VALUE
248
+ rb_bitarray_get_bit(VALUE self, VALUE bit)
249
+ {
250
+ struct bit_array *ba;
251
+ Data_Get_Struct(self, struct bit_array, ba);
252
+
253
+ ptrdiff_t index = NUM2SSIZET(bit);
254
+
255
+ int bit_value = get_bit(ba, index);
256
+
257
+ if (bit_value >= 0) {
258
+ return INT2NUM(bit_value);
259
+ } else {
260
+ rb_raise(rb_eIndexError, "index %ld out of bit array", (long)index);
261
+ }
262
+ }
263
+
264
+
265
+ static VALUE
266
+ rb_bitarray_assign_bit(VALUE self, VALUE bit, VALUE value)
267
+ {
268
+ struct bit_array *ba;
269
+ Data_Get_Struct(self, struct bit_array, ba);
270
+
271
+ ptrdiff_t index = NUM2SSIZET(bit);
272
+ int bit_value = NUM2INT(value);
273
+
274
+ int result = assign_bit(ba, index, bit_value);
275
+ if (result == 1) {
276
+ return self;
277
+ } else if (result == 0) {
278
+ rb_raise(rb_eIndexError, "index %ld out of bit array", (long)index);
279
+ } else {
280
+ rb_raise(rb_eRuntimeError, "bit value %d out of range", bit_value);
281
+ }
282
+ }
283
+
284
+
285
+ static VALUE
286
+ rb_bitarray_inspect(VALUE self)
287
+ {
288
+ struct bit_array *ba;
289
+ Data_Get_Struct(self, struct bit_array, ba);
290
+
291
+ size_t cstr_size = ba->bits + 1;
292
+ char cstr[cstr_size];
293
+
294
+ size_t i;
295
+ for (i = 0; i < ba->bits; i++) {
296
+ cstr[i] = get_bit(ba, i) + '0';
297
+ }
298
+ cstr[ba->bits] = '\0';
299
+
300
+ VALUE str = rb_str_new2(cstr);
301
+ return str;
302
+ }
303
+
304
+
305
+ static VALUE
306
+ rb_bitarray_each(VALUE self)
307
+ {
308
+ struct bit_array *ba;
309
+ Data_Get_Struct(self, struct bit_array, ba);
310
+
311
+ size_t i;
312
+
313
+ RETURN_ENUMERATOR(self, 0, 0);
314
+ for (i = 0; i < ba->bits; i++) {
315
+ int bit_value = get_bit(ba, i);
316
+ rb_yield(INT2NUM(bit_value));
317
+ }
318
+ return self;
319
+ }
320
+
321
+
322
+ void
323
+ Init_bitarray()
324
+ {
325
+ rb_bitarray_class = rb_define_class("BitArray", rb_cObject);
326
+ rb_define_alloc_func(rb_bitarray_class, rb_bitarray_alloc);
327
+
328
+ rb_define_method(rb_bitarray_class, "initialize",
329
+ rb_bitarray_initialize, 1);
330
+ rb_define_method(rb_bitarray_class, "clone", rb_bitarray_clone, 0);
331
+ rb_define_method(rb_bitarray_class, "size", rb_bitarray_size, 0);
332
+ rb_define_alias(rb_bitarray_class, "length", "size");
333
+ rb_define_method(rb_bitarray_class, "set_bit", rb_bitarray_set_bit, 1);
334
+ rb_define_method(rb_bitarray_class, "set_all_bits",
335
+ rb_bitarray_set_all_bits, 0);
336
+ rb_define_method(rb_bitarray_class, "clear_bit", rb_bitarray_clear_bit, 1);
337
+ rb_define_method(rb_bitarray_class, "clear_all_bits",
338
+ rb_bitarray_clear_all_bits, 0);
339
+ rb_define_method(rb_bitarray_class, "[]", rb_bitarray_get_bit, 1);
340
+ rb_define_method(rb_bitarray_class, "[]=", rb_bitarray_assign_bit, 2);
341
+ rb_define_method(rb_bitarray_class, "inspect", rb_bitarray_inspect, 0);
342
+ rb_define_alias(rb_bitarray_class, "to_s", "inspect");
343
+ rb_define_method(rb_bitarray_class, "each", rb_bitarray_each, 0);
344
+
345
+ rb_include_module(rb_bitarray_class, rb_mEnumerable);
346
+ }
347
+
data/ext/extconf.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('bitarray');
data/test/bitfield.rb ADDED
@@ -0,0 +1,67 @@
1
+ # NAME: BitField
2
+ # AUTHOR: Peter Cooper
3
+ # LICENSE: MIT ( http://www.opensource.org/licenses/mit-license.php )
4
+ # COPYRIGHT: (c) 2007 Peter Cooper (http://www.petercooper.co.uk/)
5
+ # VERSION: v4
6
+ # HISTORY: v4 (fixed bug where setting 0 bits to 0 caused a set to 1)
7
+ # v3 (supports dynamic bitwidths for array elements.. now doing 32 bit widths default)
8
+ # v2 (now uses 1 << y, rather than 2 ** y .. it's 21.8 times faster!)
9
+ # v1 (first release)
10
+ #
11
+ # DESCRIPTION: Basic, pure Ruby bit field. Pretty fast (for what it is) and memory efficient.
12
+ # I've written a pretty intensive test suite for it and it passes great.
13
+ # Works well for Bloom filters (the reason I wrote it).
14
+ #
15
+ # Create a bit field 1000 bits wide
16
+ # bf = BitField.new(1000)
17
+ #
18
+ # Setting and reading bits
19
+ # bf[100] = 1
20
+ # bf[100] .. => 1
21
+ # bf[100] = 0
22
+ #
23
+ # More
24
+ # bf.to_s = "10101000101010101" (example)
25
+ # bf.total_set .. => 10 (example - 10 bits are set to "1")
26
+
27
+ class BitField
28
+ attr_reader :size
29
+ include Enumerable
30
+
31
+ ELEMENT_WIDTH = 32
32
+
33
+ def initialize(size)
34
+ @size = size
35
+ @field = Array.new(((size - 1) / ELEMENT_WIDTH) + 1, 0)
36
+ end
37
+
38
+ # Set a bit (1/0)
39
+ def []=(position, value)
40
+ if value == 1
41
+ @field[position / ELEMENT_WIDTH] |= 1 << (position % ELEMENT_WIDTH)
42
+ elsif (@field[position / ELEMENT_WIDTH]) & (1 << (position % ELEMENT_WIDTH)) != 0
43
+ @field[position / ELEMENT_WIDTH] ^= 1 << (position % ELEMENT_WIDTH)
44
+ end
45
+ end
46
+
47
+ # Read a bit (1/0)
48
+ def [](position)
49
+ @field[position / ELEMENT_WIDTH] & 1 << (position % ELEMENT_WIDTH) > 0 ? 1 : 0
50
+ end
51
+
52
+ # Iterate over each bit
53
+ def each(&block)
54
+ @size.times { |position| yield self[position] }
55
+ end
56
+
57
+ # Returns the field as a string like "0101010100111100," etc.
58
+ def to_s
59
+ inject("") { |a, b| a + b.to_s }
60
+ end
61
+
62
+ # Returns the total number of bits that are set
63
+ # (The technique used here is about 6 times faster than using each or inject direct on the bitfield)
64
+ def total_set
65
+ @field.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a }
66
+ end
67
+ end
data/test/bm.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'bitfield'
2
+ require 'bitarray'
3
+ require 'benchmark'
4
+
5
+ Benchmark.bm(24) { |bm|
6
+ puts "------------------------ Object instantiation."
7
+ bm.report("BitField initialize") { 10000.times { BitField.new(256) } }
8
+ bm.report("BitArray initialize") { 10000.times { BitArray.new(256) } }
9
+
10
+ bf = BitField.new(256)
11
+ ba = BitArray.new(256)
12
+
13
+ puts "------------------------ Element Reading"
14
+ bm.report("BitField []") { 10000.times { bf[rand(256)] } }
15
+ bm.report("BitArray []") { 10000.times { ba[rand(256)] } }
16
+
17
+ puts "------------------------ Element Writing"
18
+ bm.report("BitField []=") { 10000.times { bf[rand(256)] = [0,1][rand(2)] } }
19
+ bm.report("BitArray []=") { 10000.times { ba[rand(256)] = [0,1][rand(2)] } }
20
+
21
+ puts "------------------------ Element Enumeration"
22
+ bm.report("BitField each") { 10000.times { bf.each {|b| b } } }
23
+ bm.report("BitArray each") { 10000.times { ba.each {|b| b } } }
24
+
25
+ puts "------------------------ To String"
26
+ bm.report("BitField to_s") { 10000.times { bf.to_s } }
27
+ bm.report("BitArray to_s") { 10000.times { ba.to_s } }
28
+
29
+ puts "------------------------ Set All"
30
+ bm.report("BitArray set_all_bits") { 10000.times { ba.set_all_bits} }
31
+
32
+ puts "------------------------ Clear All"
33
+ bm.report("BitArray clear_all_bits") { 10000.times { ba.clear_all_bits } }
34
+
35
+ puts "------------------------ Clone"
36
+ bm.report("BitArray clone") { 10000.times { ba.clone } }
37
+ }
38
+
data/test/test.rb ADDED
@@ -0,0 +1,91 @@
1
+ # Peter Cooper's BitField test file, modified for BitArray.
2
+ # http://snippets.dzone.com/posts/show/4234
3
+ require "test/unit"
4
+ require "bitarray"
5
+
6
+ class TestLibraryFileName < Test::Unit::TestCase
7
+ def setup
8
+ @public_ba = BitArray.new(1000)
9
+ end
10
+
11
+ def test_basic
12
+ assert_equal 0, BitArray.new(100)[0]
13
+ assert_equal 0, BitArray.new(100)[1]
14
+ end
15
+
16
+ def test_setting_and_unsetting
17
+ @public_ba[100] = 1
18
+ assert_equal 1, @public_ba[100]
19
+ @public_ba[100] = 0
20
+ assert_equal 0, @public_ba[100]
21
+ end
22
+
23
+ def test_random_setting_and_unsetting
24
+ 100.times do
25
+ index = rand(1000)
26
+ @public_ba[index] = 1
27
+ assert_equal 1, @public_ba[index]
28
+ @public_ba[index] = 0
29
+ assert_equal 0, @public_ba[index]
30
+ end
31
+ end
32
+
33
+ def test_multiple_setting
34
+ 1.upto(999) do |pos|
35
+ 2.times { @public_ba[pos] = 1 }
36
+ assert_equal 1, @public_ba[pos]
37
+ end
38
+ end
39
+
40
+ def test_multiple_unsetting
41
+ 1.upto(999) do |pos|
42
+ 2.times { @public_ba[pos] = 0 }
43
+ assert_equal 0, @public_ba[pos]
44
+ end
45
+ end
46
+
47
+ def test_size
48
+ assert_equal 1000, @public_ba.size
49
+ end
50
+
51
+
52
+ def test_to_s
53
+ ba = BitArray.new(10)
54
+ ba[1] = 1
55
+ ba[5] = 1
56
+ assert_equal "0100010000", ba.to_s
57
+ end
58
+
59
+
60
+ def test_set_all_bits
61
+ ba = BitArray.new(10)
62
+ ba.set_all_bits
63
+ assert_equal "1111111111", ba.to_s
64
+ end
65
+
66
+ def test_clear_all_bits
67
+ ba = BitArray.new(10)
68
+ ba[1] = 1
69
+ ba[5] = 1
70
+ ba.clear_all_bits
71
+ assert_equal "0000000000", ba.to_s
72
+ end
73
+
74
+ def test_clone
75
+ ba = BitArray.new(10)
76
+ ba[1] = 1
77
+ ba[5] = 1
78
+ ba_clone = ba.clone
79
+ assert_equal ba_clone.to_s, ba.to_s
80
+ end
81
+
82
+ # This method is not implemented yet.
83
+
84
+ #def test_total_set
85
+ # bf = BitArray.new(10)
86
+ # bf[1] = 1
87
+ # bf[5] = 1
88
+ # assert_equal 2, bf.total_set
89
+ #end
90
+ end
91
+
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ingramj-bitarray
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - James E. Ingram
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-23 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A bit array class for Ruby, implemented as a C extension. Includes methods for setting and clearing individual bits, and all bits at once. Also has the standard array access methods, [] and []=, and it mixes in Enumerable.
17
+ email: ingramj@gmail.com
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/extconf.rb
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README
25
+ files:
26
+ - .gitignore
27
+ - LICENSE
28
+ - README
29
+ - Rakefile
30
+ - TODO
31
+ - VERSION
32
+ - bitarray.gemspec
33
+ - ext/bitarray.c
34
+ - ext/extconf.rb
35
+ - test/bitfield.rb
36
+ - test/bm.rb
37
+ - test/test.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/ingramj/bitarray
40
+ post_install_message:
41
+ rdoc_options:
42
+ - --charset=UTF-8
43
+ - --exclude
44
+ - ext/Makefile
45
+ - --title
46
+ - " BitArray Documentation"
47
+ require_paths:
48
+ - ext
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.9.1
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.2.0
65
+ signing_key:
66
+ specification_version: 2
67
+ summary: A bitarray class for Ruby, implemented as a C extension.
68
+ test_files:
69
+ - test/bitfield.rb
70
+ - test/test.rb
71
+ - test/bm.rb