bitary 0.1.6 → 0.1.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bed2641b2bb380989c96dcc95710be56b64711c28723f3ca5f3f82fd7119bc7e
4
- data.tar.gz: 8b7aaf05d552014d77d42707453c5c4c6d84aefb2bd5d382376cdb152ce52068
3
+ metadata.gz: 293fa51d8a5a4b4cda3a7a283737d0695b84cfcb55414afde3b9c5bb6f9688aa
4
+ data.tar.gz: 6d6541faa0fed549f62a3a1b99a293ca4422511c34527a7278ea7459683f506a
5
5
  SHA512:
6
- metadata.gz: fb6ad75f7e41ef52bdd71a78ac341381671264eb86e9b90cea66d36cbdbf751ff28e0a072a1479a9474bb68e111c983bcf093936ce08b1fac60b584ec2b7e5d0
7
- data.tar.gz: bb66c485748c97732da3def70727dbc822704d21e1f2aad31cf810179db6e4154e3aa0c079a3a96a203c6e7e332865e8302428fada04b30f0671f314cbd8d772
6
+ metadata.gz: 0a81bd80568d6b5fcb20d951f0b193f98941adafd448a896f0a68ae8c97eabecca07a34a2db1d48f4e630a64d1be165ed4efe5f370bc1aabd36f78de4a5b0e7d
7
+ data.tar.gz: 94f16667978d9d9be2ccf141c6539834d7f3502397db12feee83424eb0586ace151be1ca7bee960b5bc40ba0ec6e9e12c0879c74f700d1cd86c35e21f85337bb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## [0.1.7] - 2024-04-01
2
+
3
+ - loads of refactoring and perf improvements
4
+ - Bitary now acts as the logical layer, whereas Bitwarr acts as the business layer
5
+
6
+ ## [0.1.6] - 2024-03-31
7
+
8
+ - enhance global perf by remove useless and heavy error handling
9
+
1
10
  ## [0.1.5] - 2024-03-31
2
11
 
3
12
  - enhance performance of #each_byte (4 seconds faster on average)
@@ -5,101 +5,73 @@ class Bitary
5
5
  attr_reader :bpi, :bitsize
6
6
 
7
7
  def initialize(initial_data, bpi: Bitary::LONG)
8
- check_initial_data(initial_data)
9
- check_bpi(bpi)
8
+ @bitsize = init_bitsize(initial_data, bpi)
9
+ @array = init_array(initial_data, @bitsize, bpi)
10
+ @bpi = init_bpi(initial_data, bpi)
10
11
 
11
- @bpi = bpi
12
- @bitsize = init_bitsize(initial_data)
13
- @array = init_array(initial_data)
12
+ self.bpi = bpi
14
13
  end
15
14
 
16
- def method_missing(method, *, &)
17
- @array.respond_to?(method) ? @array.send(method, *, &) : super
18
- end
19
-
20
- def respond_to_missing?(method, include_all = false)
21
- @array.respond_to?(method, include_all) || super
22
- end
23
-
24
- def [](bit_index)
25
- @array[item_index(bit_index)]
26
- end
15
+ def [](bit_index) = @array[item_index(bit_index)]
27
16
 
28
17
  def []=(bit_index, value)
29
- raise ArgumentError unless value.is_a?(Integer)
30
-
31
18
  @array[item_index(bit_index)] = value
32
19
  end
33
20
 
34
- def item_index(bit_index)
35
- check_bit_index(bit_index)
36
-
37
- bit_index / @bpi
38
- end
39
-
40
- def bit_at(index)
41
- operate_bit_at(:get, index)
42
- end
43
-
44
- def bit_at!(index)
45
- operate_bit_at!(:set, index)
46
- end
21
+ def bit_at(index) = (self[index] >> (@bpi - (index % @bpi) - 1)) & 0x1
22
+ def bit_at!(index) = self[index] |= 2**(@bpi - (index % @bpi) - 1)
47
23
 
48
24
  def unbit_at!(index)
49
- operate_bit_at!(:unset, index)
25
+ self[index] &= ((2**@bpi) - 1 - (2**(@bpi - (index % @bpi) - 1)))
50
26
  end
51
27
 
52
- def each_byte
28
+ def to_s = @array.map { |item| to_binstr(item) }.join(' ')
29
+
30
+ def each_byte(&proc)
53
31
  @array.each do |item|
54
- (@bpi / Bitary::BYTE).times do |i|
55
- byte = (item >> (@bpi - (Bitary::BYTE * (i + 1))))
56
- yield byte
57
- end
32
+ explode_item(item, Bitary::BYTE, @bpi, &proc)
58
33
  end
59
34
  end
60
35
 
61
- def to_s
62
- @array.map { |item| format("%0#{@bpi}d", item.to_s(2)) }.join(' ')
63
- end
64
-
65
36
  def bpi=(value)
66
- check_bpi(value)
37
+ return if value == @bpi
67
38
 
68
39
  update_items_size!(value)
69
-
70
40
  @bpi = value
71
41
  end
72
42
 
43
+ def method_missing(method, *, &)
44
+ @array.respond_to?(method) ? @array.send(method, *, &) : super
45
+ end
46
+
47
+ def respond_to_missing?(method, include_all = false)
48
+ @array.respond_to?(method, include_all) || super
49
+ end
50
+
73
51
  private
74
52
 
75
- def init_bitsize(initial_data)
76
- initial_data.is_a?(Array) ? @bpi * initial_data.length : initial_data
53
+ def init_bpi(initial_data, bpi)
54
+ initial_data.is_a?(Array) ? Bitary::BYTE : bpi
55
+ end
56
+
57
+ def init_bitsize(initial_data, bpi)
58
+ initial_data.is_a?(Array) ? bpi * initial_data.length : initial_data
77
59
  end
78
60
 
79
- def init_array(initial_data)
61
+ def init_array(initial_data, bitsize, bpi)
80
62
  if initial_data.is_a?(Array)
81
63
  initial_data.clone
82
64
  else
83
- [0] * (@bitsize / @bpi.to_f).ceil
65
+ [0] * (bitsize / bpi.to_f).ceil
84
66
  end
85
67
  end
86
68
 
87
- def check_initial_data(initial_data)
88
- raise ArgumentError unless [Array, Integer].include?(initial_data.class)
89
- end
90
-
91
- def check_bit_index(bit_index)
92
- raise ArgumentError unless bit_index.is_a?(Integer)
93
- raise IndexError if bit_index.negative? || bit_index >= @bitsize
69
+ def item_index(bit_index)
70
+ bit_index / @bpi
94
71
  end
95
72
 
96
- def check_bpi(bpi)
97
- raise ArgumentError unless [
98
- Bitary::BYTE,
99
- Bitary::SHORT,
100
- Bitary::INT,
101
- Bitary::LONG
102
- ].include?(bpi)
73
+ def to_binstr(item)
74
+ format("%0#{@bpi}d", item.to_s(2))
103
75
  end
104
76
 
105
77
  def operate_bit_at(operation, index)
@@ -116,29 +88,31 @@ class Bitary
116
88
  end
117
89
 
118
90
  def update_items_size!(value)
119
- if value > @bpi
120
- increase_items_size!(value)
121
- else
122
- decrease_items_size!(value)
123
- end
91
+ value > @bpi ? increase_items_size!(value) : decrease_items_size!(value)
92
+ end
93
+
94
+ def append_bits(item, bpi, addend)
95
+ (item << bpi) | addend
124
96
  end
125
97
 
126
98
  def increase_items_size(array, new_size, bpi)
127
99
  processed_bits = 0
128
- array.each_with_object([0]) do |value, acc|
129
- offset = bpi
130
- if processed_bits >= new_size
131
- offset = 0
100
+ res = array.each_with_object([0]) do |item, acc|
101
+ if processed_bits == new_size
132
102
  acc << 0
133
103
  processed_bits = 0
134
104
  end
135
105
 
136
- acc[-1] = Factory.make('Handler::Append', acc[-1]).execute(
137
- offset:,
138
- value:
139
- )
106
+ acc[-1] = append_bits(acc[-1], bpi, item)
107
+ processed_bits += bpi
108
+ end
109
+
110
+ while processed_bits < new_size
111
+ res[-1] = append_bits(res[-1], bpi, 0)
140
112
  processed_bits += bpi
141
113
  end
114
+
115
+ res
142
116
  end
143
117
 
144
118
  def increase_items_size!(value)
@@ -147,7 +121,9 @@ class Bitary
147
121
 
148
122
  def decrease_items_size(array, new_size, bpi)
149
123
  array.each_with_object([]) do |item, acc|
150
- acc.concat(explode_item(item, new_size, bpi))
124
+ explode_item(item, new_size, bpi) do |new_item|
125
+ acc << new_item
126
+ end
151
127
  end
152
128
  end
153
129
 
@@ -156,16 +132,10 @@ class Bitary
156
132
  end
157
133
 
158
134
  def explode_item(item, new_size, bpi)
159
- res = []
160
- offset = bpi
161
135
  mask = (2**new_size) - 1
162
-
163
- while offset.positive?
164
- offset -= new_size
165
- res << ((item >> offset) & mask)
136
+ (bpi / new_size).times do |i|
137
+ yield ((item >> (bpi - (new_size * (i + 1)))) & mask)
166
138
  end
167
-
168
- res
169
139
  end
170
140
  end
171
141
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Bitary
4
- VERSION = '0.1.6'
4
+ VERSION = '0.1.8'
5
5
  end
data/lib/bitary.rb CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  require_relative 'bitary/size'
4
4
  require_relative 'bitary/version'
5
- require_relative 'bitary/handler'
6
5
  require_relative 'bitary/factory'
7
6
  require_relative 'bitary/bitwarr'
8
7
  require_relative 'bitary/decorator'
@@ -12,17 +11,24 @@ class Bitary
12
11
  include Size
13
12
 
14
13
  def initialize(initial_data, bpi: LONG)
15
- @internal_array = Factory.make('Bitwarr', initial_data, bpi:)
14
+ check_initial_data(initial_data)
15
+ check_bpi(bpi)
16
+
17
+ @bitwarr = Factory.make('Bitwarr', initial_data, bpi:)
16
18
  end
17
19
 
18
20
  def [](index)
19
- @internal_array.bit_at(index)
21
+ check_bit_index(index)
22
+
23
+ @bitwarr.bit_at(index)
20
24
  end
21
25
 
22
26
  def []=(index, value)
27
+ check_bit_index(index)
28
+
23
29
  case Factory.make('Mapper::ObjToBit').map(value)
24
- when 0 then @internal_array.unbit_at!(index)
25
- else @internal_array.bit_at!(index)
30
+ when 0 then @bitwarr.unbit_at!(index)
31
+ else @bitwarr.bit_at!(index)
26
32
  end
27
33
  end
28
34
 
@@ -35,27 +41,44 @@ class Bitary
35
41
  end
36
42
 
37
43
  def each_byte(&)
38
- @internal_array.each_byte(&)
44
+ @bitwarr.each_byte(&)
39
45
  end
40
46
 
41
47
  def to_a
42
- @internal_array.to_a
48
+ @bitwarr.to_a
43
49
  end
44
50
 
45
51
  def to_s
46
- @internal_array.to_s
52
+ @bitwarr.to_s
47
53
  end
48
54
 
49
55
  def bpi=(value)
50
- @internal_array.bpi = value
56
+ check_bpi(value)
57
+
58
+ @bitwarr.bpi = value
51
59
  end
52
60
 
53
61
  def size
54
- @internal_array.bitsize
62
+ @bitwarr.bitsize
55
63
  end
56
64
 
57
65
  def bpi
58
- @internal_array.bpi
66
+ @bitwarr.bpi
67
+ end
68
+
69
+ private
70
+
71
+ def check_initial_data(initial_data)
72
+ raise ArgumentError unless [Array, Integer].include?(initial_data.class)
73
+ end
74
+
75
+ def check_bpi(bpi)
76
+ raise ArgumentError unless [BYTE, SHORT, INT, LONG].include?(bpi)
77
+ end
78
+
79
+ def check_bit_index(bit_index)
80
+ raise ArgumentError unless bit_index.is_a?(Integer)
81
+ raise IndexError if bit_index.negative? || bit_index >= @bitwarr.bitsize
59
82
  end
60
83
 
61
84
  alias at []
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitary
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maximilien Ballesteros
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-31 00:00:00.000000000 Z
11
+ date: 2024-04-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby-based implementation of the bit array data structure
14
14
  email:
@@ -29,11 +29,6 @@ files:
29
29
  - lib/bitary/decorator/single_method.rb
30
30
  - lib/bitary/decorator/single_method/non_nil_enforcer.rb
31
31
  - lib/bitary/factory.rb
32
- - lib/bitary/handler.rb
33
- - lib/bitary/handler/append.rb
34
- - lib/bitary/handler/get.rb
35
- - lib/bitary/handler/set.rb
36
- - lib/bitary/handler/unset.rb
37
32
  - lib/bitary/mapper.rb
38
33
  - lib/bitary/mapper/int_to_bit.rb
39
34
  - lib/bitary/mapper/obj_to_bit.rb
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Bitary
4
- class Handler
5
- class Append < Bitary::Handler
6
- def execute(**kwargs)
7
- (@value << kwargs[:offset]) | kwargs[:value]
8
- end
9
- end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Bitary
4
- class Handler
5
- class Get < Bitary::Handler
6
- def execute(**kwargs)
7
- (@value >> (kwargs[:size] - kwargs[:index] - 1)) & 0x1
8
- end
9
- end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Bitary
4
- class Handler
5
- class Set < Bitary::Handler
6
- def execute(**kwargs)
7
- @value | (2**(kwargs[:size] - kwargs[:index] - 1))
8
- end
9
- end
10
- end
11
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Bitary
4
- class Handler
5
- class Unset < Bitary::Handler
6
- def execute(**kwargs)
7
- size = kwargs[:size]
8
- index = kwargs[:index]
9
- @value & ((2**size) - 1 - (2**(size - index - 1)))
10
- end
11
- end
12
- end
13
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'handler/set'
4
- require_relative 'handler/unset'
5
- require_relative 'handler/get'
6
- require_relative 'handler/append'
7
-
8
- class Bitary
9
- class Handler
10
- attr_reader :value
11
-
12
- def initialize(value)
13
- @value = value
14
- end
15
-
16
- def execute(**kwargs)
17
- raise NotImplementedError
18
- end
19
- end
20
- end