bitset 1.1.0 → 1.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.
- checksums.yaml +4 -4
- data/README.markdown +12 -1
- data/VERSION +1 -1
- data/bitset.gemspec +3 -3
- data/ext/bitset/bitset.c +24 -10
- data/lib/bitset.rb +15 -10
- data/spec/bitset_spec.rb +13 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f092c73af4ffc1b72421acc789fd93e5ad55560
|
|
4
|
+
data.tar.gz: 7049663c15cbda4765a9f85e60854450418ae078
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c1b6a3553fb32e640d0fe66da0c5dd7b6b0339a4ac3b3b89c853f72bcfa4cdd0da20788ccf09af1fb057158bb314489620fdd7b6c273b50ab7f0c4175dccc03d
|
|
7
|
+
data.tar.gz: 35a517b590357d9940786448605fa124f33d4e4d55abd447e5793f2572b27c2a2a1df31c51113cb6ef8070ff0518ecb0da6f5f7420cec20837d45591f00d3442
|
data/README.markdown
CHANGED
|
@@ -35,6 +35,17 @@ We can also create a bitset based on a string of ones and zeros.
|
|
|
35
35
|
>> Bitset.from_s('00010001')
|
|
36
36
|
=> 00010001
|
|
37
37
|
|
|
38
|
+
or from an array. Falsey values (false and nil) are converted to
|
|
39
|
+
zeroes; all other values, including 0 and "", are converted to ones.
|
|
40
|
+
|
|
41
|
+
>> Bitset.new [false, nil, 3, 0]
|
|
42
|
+
=> 0011
|
|
43
|
+
|
|
44
|
+
To input an array of ones and zeroes:
|
|
45
|
+
|
|
46
|
+
>> Bitset.new([0,1,1,0].map(&:positive?))
|
|
47
|
+
=> 0110
|
|
48
|
+
|
|
38
49
|
Obviously you can also set and clear bits...
|
|
39
50
|
|
|
40
51
|
>> bitset = Bitset.new(8)
|
|
@@ -52,7 +63,7 @@ Obviously you can also set and clear bits...
|
|
|
52
63
|
>> bitset.clear(1, 5)
|
|
53
64
|
=> 00010001
|
|
54
65
|
|
|
55
|
-
Arrays of
|
|
66
|
+
Arrays of Integers can also be passed to #clear and #set (c/o brendon9x).
|
|
56
67
|
|
|
57
68
|
The point of a bitset is to be, effectively, an array of single bits. It should
|
|
58
69
|
support basic set and bitwise operations. So, let's look at a few of those.
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.2.0
|
data/bitset.gemspec
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
|
-
# stub: bitset 1.
|
|
5
|
+
# stub: bitset 1.2.0 ruby lib
|
|
6
6
|
# stub: ext/bitset/extconf.rb
|
|
7
7
|
|
|
8
8
|
Gem::Specification.new do |s|
|
|
9
9
|
s.name = "bitset".freeze
|
|
10
|
-
s.version = "1.
|
|
10
|
+
s.version = "1.2.0"
|
|
11
11
|
|
|
12
12
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
13
13
|
s.require_paths = ["lib".freeze]
|
|
14
14
|
s.authors = ["Tyler McMullen".freeze]
|
|
15
|
-
s.date = "2018-01
|
|
15
|
+
s.date = "2018-05-01"
|
|
16
16
|
s.description = "A fast C-based Bitset. It supports the standard set operations as well as operations you may expect on bit arrays,such as popcount.".freeze
|
|
17
17
|
s.email = "eric.boesch@nist.gov".freeze
|
|
18
18
|
s.extensions = ["ext/bitset/extconf.rb".freeze]
|
data/ext/bitset/bitset.c
CHANGED
|
@@ -19,6 +19,14 @@ typedef struct {
|
|
|
19
19
|
#define INTS(_bs) (((_bs)->len+63) >> 6)
|
|
20
20
|
// 2^6=64
|
|
21
21
|
|
|
22
|
+
#define _bit_no(bit) ((bit) & 0x3f)
|
|
23
|
+
#define _bit_segment(bit) ((bit) >> 6)
|
|
24
|
+
#define _bit_mask(bit) (((uint64_t) 1) << _bit_no(bit))
|
|
25
|
+
#define _seg_no_to_bit_no(seg_no) ((seg_no) << 6)
|
|
26
|
+
#define _get_bit(bs, idx) ((bs)->data[_bit_segment(idx)] & _bit_mask(idx))
|
|
27
|
+
#define _set_bit(bs, idx) ((bs)->data[_bit_segment(idx)] |= _bit_mask(idx))
|
|
28
|
+
#define _clear_bit(bs, idx) ((bs)->data[_bit_segment(idx)] &= ~_bit_mask(idx))
|
|
29
|
+
|
|
22
30
|
Bitset * bitset_new() {
|
|
23
31
|
return (Bitset *) calloc(1, sizeof(Bitset));
|
|
24
32
|
}
|
|
@@ -47,9 +55,23 @@ static VALUE rb_bitset_alloc(VALUE klass) {
|
|
|
47
55
|
return obj;
|
|
48
56
|
}
|
|
49
57
|
|
|
50
|
-
static VALUE rb_bitset_initialize(VALUE self, VALUE
|
|
58
|
+
static VALUE rb_bitset_initialize(VALUE self, VALUE ary) {
|
|
51
59
|
Bitset * bs = get_bitset(self);
|
|
52
|
-
|
|
60
|
+
if (RB_TYPE_P(ary, T_ARRAY)) {
|
|
61
|
+
int i;
|
|
62
|
+
int len = (int) RARRAY_LEN(ary);
|
|
63
|
+
bitset_setup(bs, len);
|
|
64
|
+
for (i = 0; i < len; ++i) {
|
|
65
|
+
// This could be more efficient, but if you're converting
|
|
66
|
+
// from a Ruby array of bits, you're not looking
|
|
67
|
+
// at blazing speed anyhow.
|
|
68
|
+
if (RTEST(rb_ary_entry(ary, i))) {
|
|
69
|
+
_set_bit(bs, i);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
bitset_setup(bs, NUM2INT(ary));
|
|
74
|
+
}
|
|
53
75
|
return self;
|
|
54
76
|
}
|
|
55
77
|
|
|
@@ -63,14 +85,6 @@ static void raise_index_error() {
|
|
|
63
85
|
rb_raise(rb_eIndexError, "Index out of bounds");
|
|
64
86
|
}
|
|
65
87
|
|
|
66
|
-
#define _bit_no(bit) ((bit) & 0x3f)
|
|
67
|
-
#define _bit_segment(bit) ((bit) >> 6)
|
|
68
|
-
#define _bit_mask(bit) (((uint64_t) 1) << _bit_no(bit))
|
|
69
|
-
#define _seg_no_to_bit_no(seg_no) ((seg_no) << 6)
|
|
70
|
-
#define _get_bit(bs, idx) ((bs)->data[_bit_segment(idx)] & _bit_mask(idx))
|
|
71
|
-
#define _set_bit(bs, idx) ((bs)->data[_bit_segment(idx)] |= _bit_mask(idx))
|
|
72
|
-
#define _clear_bit(bs, idx) ((bs)->data[_bit_segment(idx)] &= ~_bit_mask(idx))
|
|
73
|
-
|
|
74
88
|
static void validate_index(Bitset * bs, int idx) {
|
|
75
89
|
if(idx < 0 || idx >= bs->len)
|
|
76
90
|
raise_index_error();
|
data/lib/bitset.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
require "bitset/bitset"
|
|
2
2
|
|
|
3
3
|
class Bitset
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
#
|
|
10
|
-
#
|
|
4
|
+
# @return [String] This bitset packed into bytes.
|
|
5
|
+
#
|
|
6
|
+
# The first 3 bits represent the number of padding bits in the final
|
|
7
|
+
# byte of the string.
|
|
8
|
+
#
|
|
9
|
+
# This is somewhat redundant with Marshal.dump and Marshal.load, but
|
|
10
|
+
# it does save a few bytes.
|
|
11
11
|
def pack
|
|
12
12
|
# Number of bits of zero padding in this representation.
|
|
13
13
|
padding_bits = (size+3) & 7
|
|
@@ -15,11 +15,16 @@ class Bitset
|
|
|
15
15
|
[("%03b" % padding_bits) + self.to_s].pack("b*")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
def inspect
|
|
19
|
+
"#{self.class.name}:#{to_s}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param [String] Output from {#pack}
|
|
23
|
+
#
|
|
24
|
+
# @return [Bitset] A duplicate of the input to {#pack}
|
|
19
25
|
def self.unpack str
|
|
20
|
-
bits = str.unpack("b*")
|
|
26
|
+
bits = str.unpack("b*").first
|
|
21
27
|
padding_bits = bits[0...3].to_i(2)
|
|
22
28
|
from_s(bits[3 .. -1 - padding_bits])
|
|
23
29
|
end
|
|
24
|
-
|
|
25
30
|
end
|
data/spec/bitset_spec.rb
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
require 'bitset'
|
|
2
2
|
|
|
3
3
|
describe Bitset do
|
|
4
|
-
it 'can be initialized' do
|
|
4
|
+
it 'can be initialized by size' do
|
|
5
5
|
Bitset.new(64)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
it 'can be initialized by array' do
|
|
9
|
+
Bitset.new([false, nil, 3, 0]).to_s == "0011"
|
|
10
|
+
end
|
|
11
|
+
|
|
8
12
|
it 'raises ArgumentError wihen initialized with no argument' do
|
|
9
13
|
expect { Bitset.new }.to raise_error(ArgumentError)
|
|
10
14
|
end
|
|
@@ -110,13 +114,13 @@ describe Bitset do
|
|
|
110
114
|
expect(bs.clear?(0,2,3,6)).to be true
|
|
111
115
|
end
|
|
112
116
|
|
|
113
|
-
it '
|
|
117
|
+
it 'works with the full range of 64 bit values' do
|
|
114
118
|
bs = Bitset.new(68)
|
|
115
119
|
bs.set 0, 2, 66
|
|
116
120
|
expect(bs.clear?(32, 33, 34)).to be true
|
|
117
121
|
end
|
|
118
122
|
|
|
119
|
-
it 'returns
|
|
123
|
+
it 'returns false if not all bits indexed are clear' do
|
|
120
124
|
bs = Bitset.new(8)
|
|
121
125
|
bs.set 1, 4
|
|
122
126
|
expect(bs.clear?(1,2,6)).to be false
|
|
@@ -416,5 +420,10 @@ describe Bitset do
|
|
|
416
420
|
end
|
|
417
421
|
end
|
|
418
422
|
end
|
|
419
|
-
|
|
423
|
+
|
|
424
|
+
describe :inspect do
|
|
425
|
+
it "returns expected output" do
|
|
426
|
+
expect(Bitset.from_s("1011").inspect).to eq("Bitset:1011")
|
|
427
|
+
end
|
|
428
|
+
end
|
|
420
429
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bitset
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tyler McMullen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-01
|
|
11
|
+
date: 2018-05-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A fast C-based Bitset. It supports the standard set operations as well
|
|
14
14
|
as operations you may expect on bit arrays,such as popcount.
|