bitset 0.0.3 → 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/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
|
|