ingramj-bitarray 0.1.1 → 0.2.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/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
|
|