ingramj-bitarray 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/TODO +2 -2
- data/VERSION +1 -1
- data/bitarray.gemspec +1 -1
- data/ext/bitarray.c +98 -1
- data/test/bm.rb +19 -11
- data/test/test.rb +20 -10
- metadata +1 -1
data/TODO
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
* Comment code. I'd like for it to be useful as a tutorial for extension
|
2
2
|
writing, especially with regards to implementing new types.
|
3
|
-
* Implement some more methods, like
|
4
|
-
|
3
|
+
* Implement some more methods, like slice, and in-place enumerator methods
|
4
|
+
(map!, reverse!, etc).
|
5
5
|
* Maybe allow resizing.
|
6
6
|
* Write more tests
|
7
7
|
* Ruby 1.8 compatibility. This will probably involve just changing some of the
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/bitarray.gemspec
CHANGED
data/ext/bitarray.c
CHANGED
@@ -81,6 +81,18 @@ toggle_bit(struct bit_array *ba, ptrdiff_t bit)
|
|
81
81
|
}
|
82
82
|
|
83
83
|
|
84
|
+
/* Toggle the state of all bits. */
|
85
|
+
static int
|
86
|
+
toggle_all_bits(struct bit_array *ba)
|
87
|
+
{
|
88
|
+
int i;
|
89
|
+
for(i = 0; i < ba->array_size; i++) {
|
90
|
+
ba->array[i] ^= ~0ul; /* ~0 = all bits set. */
|
91
|
+
}
|
92
|
+
return 1;
|
93
|
+
}
|
94
|
+
|
95
|
+
|
84
96
|
/* Assign the specified value to a bit. Return 1 on success, 0 on invalid bit
|
85
97
|
* index, and -1 on invalid value. */
|
86
98
|
static int
|
@@ -114,7 +126,29 @@ get_bit(struct bit_array *ba, ptrdiff_t bit)
|
|
114
126
|
}
|
115
127
|
|
116
128
|
|
117
|
-
/*
|
129
|
+
/* Return the number of set bits in the array. */
|
130
|
+
static size_t
|
131
|
+
total_set(struct bit_array *ba)
|
132
|
+
{
|
133
|
+
/* This is basically the algorithm from K&R, with a running total for all
|
134
|
+
* array elements. There are faster algorithms, but this one is simpler to
|
135
|
+
* implement. The running time is proportionate to the number of set bits.
|
136
|
+
*/
|
137
|
+
size_t count = 0;
|
138
|
+
int i;
|
139
|
+
unsigned x;
|
140
|
+
for (i = 0; i < ba->array_size; i++) {
|
141
|
+
x = ba->array[i];
|
142
|
+
while (x) {
|
143
|
+
x &= x - 1;
|
144
|
+
count++;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
return count;
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
/* Ruby Interface Functions. */
|
118
152
|
|
119
153
|
static VALUE rb_bitarray_class;
|
120
154
|
|
@@ -201,6 +235,22 @@ rb_bitarray_size(VALUE self)
|
|
201
235
|
}
|
202
236
|
|
203
237
|
|
238
|
+
/* call-seq:
|
239
|
+
* bitarray.total_set -> int
|
240
|
+
*
|
241
|
+
* Return the number of set (1) bits in _bitarray_.
|
242
|
+
*/
|
243
|
+
static VALUE
|
244
|
+
rb_bitarray_total_set(VALUE self)
|
245
|
+
{
|
246
|
+
struct bit_array *ba;
|
247
|
+
Data_Get_Struct(self, struct bit_array, ba);
|
248
|
+
|
249
|
+
size_t count = total_set(ba);
|
250
|
+
return SIZET2NUM(count);
|
251
|
+
}
|
252
|
+
|
253
|
+
|
204
254
|
/* call-seq:
|
205
255
|
* bitarray.set_bit(index) -> bitarray
|
206
256
|
*
|
@@ -285,6 +335,48 @@ rb_bitarray_clear_all_bits(VALUE self)
|
|
285
335
|
}
|
286
336
|
|
287
337
|
|
338
|
+
/* call-seq:
|
339
|
+
* bitarray.toggle_bit(index) -> bitarray
|
340
|
+
*
|
341
|
+
* Toggles the bit at _index_ to 0. Negative indices count backwards from the
|
342
|
+
* end of _bitarray_. If _index_ is greater than the capacity of _bitarray_, an
|
343
|
+
* +IndexError+ is raised.
|
344
|
+
*/
|
345
|
+
static VALUE
|
346
|
+
rb_bitarray_toggle_bit(VALUE self, VALUE bit)
|
347
|
+
{
|
348
|
+
struct bit_array *ba;
|
349
|
+
Data_Get_Struct(self, struct bit_array, ba);
|
350
|
+
|
351
|
+
ptrdiff_t index = NUM2SSIZET(bit);
|
352
|
+
|
353
|
+
if (toggle_bit(ba, index)) {
|
354
|
+
return self;
|
355
|
+
} else {
|
356
|
+
rb_raise(rb_eIndexError, "index %ld out of bit array", (long)index);
|
357
|
+
}
|
358
|
+
}
|
359
|
+
|
360
|
+
|
361
|
+
/* call-seq:
|
362
|
+
* bitarray.toggle_all_bits -> bitarray
|
363
|
+
*
|
364
|
+
* Toggle all bits.
|
365
|
+
*/
|
366
|
+
static VALUE
|
367
|
+
rb_bitarray_toggle_all_bits(VALUE self)
|
368
|
+
{
|
369
|
+
struct bit_array *ba;
|
370
|
+
Data_Get_Struct(self, struct bit_array, ba);
|
371
|
+
|
372
|
+
if(toggle_all_bits(ba)) {
|
373
|
+
return self;
|
374
|
+
} else {
|
375
|
+
rb_bug("BitArray#clear_all_bits failed. This should not occur.");
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
379
|
+
|
288
380
|
/* call-seq:
|
289
381
|
* bitarray[index] -> value
|
290
382
|
*
|
@@ -417,12 +509,17 @@ Init_bitarray()
|
|
417
509
|
rb_define_alias(rb_bitarray_class, "dup", "clone");
|
418
510
|
rb_define_method(rb_bitarray_class, "size", rb_bitarray_size, 0);
|
419
511
|
rb_define_alias(rb_bitarray_class, "length", "size");
|
512
|
+
rb_define_method(rb_bitarray_class, "total_set", rb_bitarray_total_set, 0);
|
420
513
|
rb_define_method(rb_bitarray_class, "set_bit", rb_bitarray_set_bit, 1);
|
421
514
|
rb_define_method(rb_bitarray_class, "set_all_bits",
|
422
515
|
rb_bitarray_set_all_bits, 0);
|
423
516
|
rb_define_method(rb_bitarray_class, "clear_bit", rb_bitarray_clear_bit, 1);
|
424
517
|
rb_define_method(rb_bitarray_class, "clear_all_bits",
|
425
518
|
rb_bitarray_clear_all_bits, 0);
|
519
|
+
rb_define_method(rb_bitarray_class, "toggle_bit",
|
520
|
+
rb_bitarray_toggle_bit, 1);
|
521
|
+
rb_define_method(rb_bitarray_class, "toggle_all_bits",
|
522
|
+
rb_bitarray_toggle_all_bits, 0);
|
426
523
|
rb_define_method(rb_bitarray_class, "[]", rb_bitarray_get_bit, 1);
|
427
524
|
rb_define_method(rb_bitarray_class, "[]=", rb_bitarray_assign_bit, 2);
|
428
525
|
rb_define_method(rb_bitarray_class, "inspect", rb_bitarray_inspect, 0);
|
data/test/bm.rb
CHANGED
@@ -2,37 +2,45 @@ require 'bitfield'
|
|
2
2
|
require 'bitarray'
|
3
3
|
require 'benchmark'
|
4
4
|
|
5
|
-
Benchmark.bm(
|
6
|
-
puts "
|
5
|
+
Benchmark.bm(28) { |bm|
|
6
|
+
puts "---------------------------- Object instantiation."
|
7
7
|
bm.report("BitField initialize") { 10000.times { BitField.new(256) } }
|
8
8
|
bm.report("BitArray initialize") { 10000.times { BitArray.new(256) } }
|
9
9
|
|
10
10
|
bf = BitField.new(256)
|
11
11
|
ba = BitArray.new(256)
|
12
12
|
|
13
|
-
puts "
|
13
|
+
puts "---------------------------- Element Reading"
|
14
14
|
bm.report("BitField []") { 10000.times { bf[rand(256)] } }
|
15
15
|
bm.report("BitArray []") { 10000.times { ba[rand(256)] } }
|
16
16
|
|
17
|
-
puts "
|
17
|
+
puts "---------------------------- Element Writing"
|
18
18
|
bm.report("BitField []=") { 10000.times { bf[rand(256)] = [0,1][rand(2)] } }
|
19
19
|
bm.report("BitArray []=") { 10000.times { ba[rand(256)] = [0,1][rand(2)] } }
|
20
20
|
|
21
|
-
puts "
|
21
|
+
puts "---------------------------- Element Enumeration"
|
22
22
|
bm.report("BitField each") { 10000.times { bf.each {|b| b } } }
|
23
23
|
bm.report("BitArray each") { 10000.times { ba.each {|b| b } } }
|
24
24
|
|
25
|
-
puts "
|
25
|
+
puts "---------------------------- To String"
|
26
26
|
bm.report("BitField to_s") { 10000.times { bf.to_s } }
|
27
27
|
bm.report("BitArray to_s") { 10000.times { ba.to_s } }
|
28
28
|
|
29
|
-
puts "
|
29
|
+
puts "---------------------------- Total Set"
|
30
|
+
bf = BitField.new(256)
|
31
|
+
ba = BitArray.new(256)
|
32
|
+
bm.report("BitField total_set (none)") { 10000.times { bf.total_set } }
|
33
|
+
bm.report("BitArray total_set (none)") { 10000.times { ba.total_set } }
|
34
|
+
bf.each {|b| b = 1}
|
35
|
+
ba.set_all_bits
|
36
|
+
bm.report("BitField total_set (all)") { 10000.times { bf.total_set } }
|
37
|
+
bm.report("BitArray total_set (all)") { 10000.times { ba.total_set } }
|
38
|
+
|
39
|
+
puts "---------------------------- BitArray methods"
|
30
40
|
bm.report("BitArray set_all_bits") { 10000.times { ba.set_all_bits} }
|
31
|
-
|
32
|
-
puts "------------------------ Clear All"
|
33
41
|
bm.report("BitArray clear_all_bits") { 10000.times { ba.clear_all_bits } }
|
34
|
-
|
35
|
-
|
42
|
+
bm.report("BitArray toggle_bit") { 10000.times { ba.toggle_bit(1) } }
|
43
|
+
bm.report("BitArray toggle_all_bits") { 10000.times { ba.toggle_all_bits } }
|
36
44
|
bm.report("BitArray clone") { 10000.times { ba.clone } }
|
37
45
|
}
|
38
46
|
|
data/test/test.rb
CHANGED
@@ -47,7 +47,6 @@ class TestLibraryFileName < Test::Unit::TestCase
|
|
47
47
|
def test_size
|
48
48
|
assert_equal 1000, @public_ba.size
|
49
49
|
end
|
50
|
-
|
51
50
|
|
52
51
|
def test_to_s
|
53
52
|
ba = BitArray.new(10)
|
@@ -56,7 +55,6 @@ class TestLibraryFileName < Test::Unit::TestCase
|
|
56
55
|
assert_equal "0100010000", ba.to_s
|
57
56
|
end
|
58
57
|
|
59
|
-
|
60
58
|
def test_set_all_bits
|
61
59
|
ba = BitArray.new(10)
|
62
60
|
ba.set_all_bits
|
@@ -78,14 +76,26 @@ class TestLibraryFileName < Test::Unit::TestCase
|
|
78
76
|
ba_clone = ba.clone
|
79
77
|
assert_equal ba_clone.to_s, ba.to_s
|
80
78
|
end
|
81
|
-
|
82
|
-
# This method is not implemented yet.
|
83
79
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
80
|
+
def test_toggle_bit
|
81
|
+
ba = BitArray.new(10)
|
82
|
+
ba.toggle_bit 5
|
83
|
+
assert_equal 1, ba[5]
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_toggle_all_bits
|
87
|
+
ba = BitArray.new(10)
|
88
|
+
ba[1] = 1
|
89
|
+
ba[5] = 1
|
90
|
+
ba.toggle_all_bits
|
91
|
+
assert_equal "1011101111", ba.to_s
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_total_set
|
95
|
+
bf = BitArray.new(10)
|
96
|
+
bf[1] = 1
|
97
|
+
bf[5] = 1
|
98
|
+
assert_equal 2, bf.total_set
|
99
|
+
end
|
90
100
|
end
|
91
101
|
|