ingramj-bitarray 0.1.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/.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