bitset 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bitset.gemspec +2 -2
- data/ext/bitset/bitset.c +32 -2
- data/spec/bitset_spec.rb +14 -0
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/bitset.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bitset}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Tyler McMullen"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-03-03}
|
13
13
|
s.description = %q{A fast C-based Bitset. It supports the standard set operations as well as operations you may expect on bit arrays. (popcount, for instance)}
|
14
14
|
s.email = %q{tbmcmullen@gmail.com}
|
15
15
|
s.extensions = ["ext/bitset/extconf.rb"]
|
data/ext/bitset/bitset.c
CHANGED
@@ -11,6 +11,9 @@ typedef struct {
|
|
11
11
|
uint64_t * data;
|
12
12
|
} Bitset;
|
13
13
|
|
14
|
+
#define BYTES(_bs) (((_bs->len-1) >> 3) + 1)
|
15
|
+
#define INTS(_bs) (((_bs->len-1) >> 6) + 1)
|
16
|
+
|
14
17
|
Bitset * bitset_new() {
|
15
18
|
return (Bitset *) malloc(sizeof(Bitset));
|
16
19
|
}
|
@@ -56,7 +59,7 @@ void raise_index_error() {
|
|
56
59
|
}
|
57
60
|
|
58
61
|
#define _bit_segment(bit) ((bit) >> 6UL)
|
59
|
-
#define _bit_mask(bit) (
|
62
|
+
#define _bit_mask(bit) (((uint64_t) 1) << ((bit) & 0x3f))
|
60
63
|
|
61
64
|
void validate_index(Bitset * bs, int idx) {
|
62
65
|
if(idx < 0 || idx >= bs->len)
|
@@ -156,7 +159,7 @@ static VALUE rb_bitset_cardinality(VALUE self) {
|
|
156
159
|
for(i = 0; i < max; i++) {
|
157
160
|
uint64_t segment = bs->data[i];
|
158
161
|
if(i+1 == max)
|
159
|
-
segment &= ((1 << (bs->len & 0x3F)) - 1);
|
162
|
+
segment &= ((((uint64_t) 1) << (bs->len & 0x3F)) - 1);
|
160
163
|
count += __builtin_popcountll(segment);
|
161
164
|
}
|
162
165
|
return INT2NUM(count);
|
@@ -307,6 +310,31 @@ static VALUE rb_bitset_each(VALUE self) {
|
|
307
310
|
return self;
|
308
311
|
}
|
309
312
|
|
313
|
+
static VALUE rb_bitset_marshall_dump(VALUE self) {
|
314
|
+
Bitset * bs = get_bitset(self);
|
315
|
+
VALUE hash = rb_hash_new();
|
316
|
+
VALUE data = rb_str_new(bs->data, BYTES(bs));
|
317
|
+
|
318
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("len")), UINT2NUM(bs->len));
|
319
|
+
rb_hash_aset(hash, ID2SYM(rb_intern("data")), data);
|
320
|
+
|
321
|
+
return hash;
|
322
|
+
}
|
323
|
+
|
324
|
+
static VALUE rb_bitset_marshall_load(VALUE self, VALUE hash) {
|
325
|
+
Bitset * bs = get_bitset(self);
|
326
|
+
int len = NUM2INT(rb_hash_aref(hash, ID2SYM(rb_intern("len"))));
|
327
|
+
|
328
|
+
VALUE data = rb_hash_aref(hash, ID2SYM(rb_intern("data")));
|
329
|
+
|
330
|
+
bitset_setup(bs, len);
|
331
|
+
|
332
|
+
bs->data = (uint64_t *) calloc(INTS(bs), sizeof(uint64_t));
|
333
|
+
memcpy(bs->data, RSTRING_PTR(data), BYTES(bs));
|
334
|
+
|
335
|
+
return Qnil;
|
336
|
+
}
|
337
|
+
|
310
338
|
void Init_bitset() {
|
311
339
|
cBitset = rb_define_class("Bitset", rb_cObject);
|
312
340
|
rb_include_module(cBitset, rb_mEnumerable);
|
@@ -335,4 +363,6 @@ void Init_bitset() {
|
|
335
363
|
rb_define_method(cBitset, "each", rb_bitset_each, 0);
|
336
364
|
rb_define_method(cBitset, "to_s", rb_bitset_to_s, 0);
|
337
365
|
rb_define_singleton_method(cBitset, "from_s", rb_bitset_from_s, 1);
|
366
|
+
rb_define_method(cBitset, "marshal_dump", rb_bitset_marshall_dump, 0);
|
367
|
+
rb_define_method(cBitset, "marshal_load", rb_bitset_marshall_load, 1);
|
338
368
|
}
|
data/spec/bitset_spec.rb
CHANGED
@@ -136,6 +136,9 @@ describe Bitset do
|
|
136
136
|
bs = Bitset.new(10_000)
|
137
137
|
bs.set(*(0...5000).to_a)
|
138
138
|
bs.cardinality.should == 5000
|
139
|
+
|
140
|
+
bs = Bitset.from_s "01001101000000000000000000000011000010100100000000000000010000101000000000000000100000000100000000000010100100010000000010000100000100000001001000110000000000100010000000010100000000000000110000000000000000000000000100000000100010010000000000000000000001000000000000000000000000000001000000000000000000000000000100000000010010000000000000000000100100000000000000001000000010000001000000000000001000001100010001000000000000001000001000001000000000000001100010000010010001000000010000100000000000110000"
|
141
|
+
bs.cardinality.should == 63
|
139
142
|
end
|
140
143
|
end
|
141
144
|
|
@@ -250,4 +253,15 @@ describe Bitset do
|
|
250
253
|
bs.set?(0, 2, 4).should == true
|
251
254
|
end
|
252
255
|
end
|
256
|
+
|
257
|
+
describe :marshalling do
|
258
|
+
it 'can marshal and load' do
|
259
|
+
bs = Bitset.new(68)
|
260
|
+
bs.set 1, 65
|
261
|
+
|
262
|
+
serialized = Marshal.load(Marshal.dump(bs))
|
263
|
+
serialized.set?(1, 65).should == true
|
264
|
+
serialized.cardinality.should == 2
|
265
|
+
end
|
266
|
+
end
|
253
267
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.3
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Tyler McMullen
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-03-03 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|