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 CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bitset}
8
- s.version = "0.0.3"
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-02-26}
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"]
@@ -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) (1UL << ((bit) & 0x3f))
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
  }
@@ -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
- - 3
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-02-26 00:00:00 -08:00
17
+ date: 2011-03-03 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies: []
20
20