bitary 0.1.1 → 0.1.3

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: ee481b52a264fe1e578b65f0228e9a9c6e4eb57a7fa7fb224fb4c1dd31d60f0c
4
- data.tar.gz: 2529e365b65266446aace9bce47369f49615869c4c4ab6ffe134b90c61422535
3
+ metadata.gz: cc3397b948d902fe5cba56205955a01b7ad9f0d5d6eb7a1bf74984005f693114
4
+ data.tar.gz: af6673d27575273094dc34a4c67c67fbaa603de8a4e04375b0719e247f8cbcd9
5
5
  SHA512:
6
- metadata.gz: 1b549423b7cbe533c07fc54b5a4f938612889508703530336b048206f4681356fbbcb04065b7d04a887ed3f03db6ad6cb94538a4b047a6e2e7eeb4904d0af5f9
7
- data.tar.gz: 4e4831d9dcb860c06067ca92e63b41d81ac90e0d3e7aa2f0ddfd48f80f8b8352bf77c6cedbc8b5002285d29f2c6c33b9e96b1456175b1a7ebb41a272a015ce87
6
+ metadata.gz: e44836498539b643e9b75ead2d63c9b91beda96008bc11d5e10a3b354d67ad4f604b1ceee4740665c60a7eeca7ca898e3f05b22aa48d2845f10fa71914a22998
7
+ data.tar.gz: 2cc01a7ba3ab7463ab64283fb6e4f82ab8dab61865595f93bbea1efdbf966463008faf2d9dab42f8e304e1f9e6bfa57d597b7d1826ef8521e7f480d2749403f1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
- ## [Unreleased]
1
+ ## [0.1.2] - 2024-03-29
2
+
3
+ - internal refactoring of the Bitary class
4
+ - addition of integer size enum
5
+
6
+ ## [0.1.1] - 2024-03-26
7
+
8
+ - Change root namespace to a class, instead of a module
2
9
 
3
10
  ## [0.1.0] - 2024-03-26
4
11
 
5
12
  - Initial release
13
+ - Basic implementation to set/unset/get bits from the bit array
14
+ - Ability to traverse each byte of the structure
15
+ - Increase/decrease the number of bits used internally per element
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Ruby-based implementation of the bit array data structure.
4
4
 
5
- It's still under development, but as of now, it implements simple and well-optimized logic allowing you to set, unset and retrieve bits.
5
+ It's still under development, but as of now, it implements simple and well-optimized logic allowing you to set, unset and retrieve bits (as well as some extra features, see below).
6
6
 
7
7
  ## Installation
8
8
 
@@ -24,10 +24,12 @@ Documentation still needs to be written, but here is a breakdown
24
24
  of the main capabilities brought by the current bit array implementation:
25
25
 
26
26
  ```ruby
27
+ require 'bitary'
28
+
27
29
  bit_array_sz = Bitary.new(128) # give an explicit size. Defaults to 64 bits used per item
28
30
  bit_array_ar = Bitary.new(
29
31
  [255, 10, 20],
30
- bits_per_item: 8
32
+ bits_per_item: Bitary::Size::BYTE # 8 bits
31
33
  ) # create based on some integer array
32
34
 
33
35
  bit_array_sz.bits_per_item # 64
@@ -55,13 +57,13 @@ bit_array_ar.to_a # [127, 10, 20]
55
57
  bit_array_ar.to_s # "01111111 00001010 00010100"
56
58
 
57
59
  # increase/decrease bits used per item
58
- bit_array_ar.bits_per_item = 64
60
+ bit_array_ar.bits_per_item = Bitary::Size::LONG # 64 bits
59
61
  bit_array_ar.to_a # [8_325_652]
60
62
  bit_array_ar.to_s # "0000000000000000000000000000000000000000011111110000101000010100"
61
63
 
62
64
  bit_array_sz.bits_per_item # 64
63
65
  bit_array_sz.to_a # [1_099_511_627_776, 0]
64
- bit_array_sz.bits_per_item = 32
66
+ bit_array_sz.bits_per_item = Bitary::Size::INT # 32 bits
65
67
  bit_array_sz.to_a # [256, 0, 0, 0]
66
68
  ```
67
69
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Bitary
4
+ class Deptainer
5
+ def initialize
6
+ @store = {}
7
+ end
8
+
9
+ def [](key)
10
+ raise ArgumentError unless key.is_a?(Symbol)
11
+
12
+ @store[key]
13
+ end
14
+
15
+ def []=(key, value)
16
+ raise ArgumentError unless key.is_a?(Symbol)
17
+
18
+ @store[key] = value
19
+ end
20
+
21
+ def has?(key)
22
+ raise ArgumentError unless key.is_a?(Symbol)
23
+
24
+ @store.key?(key)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'deptainer'
4
+
5
+ class Bitary
6
+ class Factory
7
+ private_class_method :new
8
+ @container = Deptainer.new
9
+
10
+ def self.make(name, *, **)
11
+ raise ArgumentError unless name.is_a?(String)
12
+
13
+ name.split('::').reduce(Bitary) do |cls, str|
14
+ cls.const_get(str)
15
+ end.new(*, **)
16
+ end
17
+
18
+ def self.make_memo(name, *args, **kwargs)
19
+ raise ArgumentError unless name.is_a?(String)
20
+ if @container.has?(name.to_sym) && !args.empty? && !kwargs.empty?
21
+ raise ArgumentError
22
+ end
23
+
24
+ @container[name.to_sym] ||= make(name, *args, **kwargs)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Bitary
4
+ class Handler
5
+ class Append < Bitary::Handler
6
+ def execute(**kwargs)
7
+ raise ArgumentError unless kwargs.all? do |key, _value|
8
+ %i[offset value].include?(key)
9
+ end
10
+
11
+ offset = kwargs[:offset] or raise KeyError
12
+ value = kwargs[:value] or raise KeyError
13
+ raise ArgumentError unless offset.is_a?(Integer)
14
+ raise ArgumentError unless value.is_a?(Integer)
15
+
16
+ (@value << offset) | value
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Bitary
4
+ class Handler
5
+ class Get < Bitary::Handler
6
+ def execute(**kwargs)
7
+ raise ArgumentError unless kwargs.all? do |key, _value|
8
+ %i[index size].include?(key)
9
+ end
10
+
11
+ index = kwargs[:index] or raise KeyError
12
+ size = kwargs[:size] or raise KeyError
13
+ raise ArgumentError unless index.is_a?(Integer)
14
+ raise ArgumentError unless size.is_a?(Integer)
15
+
16
+ raise IndexError if index.negative? || index >= size
17
+
18
+ (@value >> (size - index - 1)) & 0x1
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Bitary
4
+ class Handler
5
+ class Set < Bitary::Handler
6
+ def execute(**kwargs)
7
+ raise ArgumentError unless kwargs.all? do |key, _value|
8
+ %i[index size].include?(key)
9
+ end
10
+
11
+ index = kwargs[:index] or raise KeyError
12
+ size = kwargs[:size] or raise KeyError
13
+ raise ArgumentError unless index.is_a?(Integer)
14
+ raise ArgumentError unless size.is_a?(Integer)
15
+
16
+ raise IndexError if index.negative? || index >= size
17
+
18
+ @value | (2**(size - index - 1))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Bitary
4
+ class Handler
5
+ class Unset < Bitary::Handler
6
+ def execute(**kwargs)
7
+ raise ArgumentError unless kwargs.all? do |key, _value|
8
+ %i[index size].include?(key)
9
+ end
10
+
11
+ index = kwargs[:index] or raise KeyError
12
+ size = kwargs[:size] or raise KeyError
13
+ raise ArgumentError unless index.is_a?(Integer)
14
+ raise ArgumentError unless size.is_a?(Integer)
15
+
16
+ raise IndexError if index.negative? || index >= size
17
+
18
+ @value & (((2**size) - 1) - (2**(size - index - 1)))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
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
+ raise ArgumentError unless value.is_a?(Integer)
14
+
15
+ @value = value
16
+ end
17
+
18
+ def execute(**kwargs)
19
+ raise NotImplementedError
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Bitary
4
+ module Size
5
+ BYTE = 8
6
+ SHORT = 16
7
+ INT = 32
8
+ LONG = 64
9
+ end
10
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Bitary
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.3'
5
5
  end
data/lib/bitary.rb CHANGED
@@ -1,12 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'bitary/size'
3
4
  require_relative 'bitary/version'
5
+ require_relative 'bitary/handler'
6
+ require_relative 'bitary/factory'
7
+ require_relative 'bitary/deptainer'
4
8
 
5
9
  class Bitary
10
+ include Size
11
+
6
12
  attr_reader :size, :bits_per_item
7
13
 
8
- def initialize(initial_data, bits_per_item: 64)
9
- raise ArgumentError unless [8, 16, 32, 64].include?(bits_per_item)
14
+ def initialize(initial_data, bits_per_item: LONG)
15
+ raise ArgumentError unless [BYTE, SHORT, INT, LONG].include?(bits_per_item)
10
16
 
11
17
  @size = init_size(initial_data, bits_per_item)
12
18
  @internal_array = init_internal_array(initial_data, @size, bits_per_item)
@@ -18,9 +24,12 @@ class Bitary
18
24
 
19
25
  item_index = compute_item_index(index)
20
26
  item_bit_size = compute_item_bit_size(item_index)
21
- offset = compute_relative_offset(index, item_bit_size)
27
+ item = @internal_array[item_index]
22
28
 
23
- get_bit(@internal_array[item_index], offset)
29
+ Factory.make('Handler::Get', item).execute(
30
+ index: index % @bits_per_item,
31
+ size: item_bit_size
32
+ )
24
33
  end
25
34
 
26
35
  def []=(index, value)
@@ -29,22 +38,32 @@ class Bitary
29
38
  bit = map_to_bit(value)
30
39
  item_index = compute_item_index(index)
31
40
  item_bit_size = compute_item_bit_size(item_index)
32
- offset = compute_relative_offset(index, item_bit_size)
41
+ item = @internal_array[item_index]
33
42
 
34
43
  @internal_array[item_index] =
35
44
  if bit == 1
36
- set_bit(@internal_array[item_index], offset)
45
+ Factory.make('Handler::Set', item).execute(
46
+ index: index % @bits_per_item,
47
+ size: item_bit_size
48
+ )
37
49
  else
38
- unset_bit(
39
- @internal_array[item_index],
40
- offset,
41
- item_bit_size
50
+ Factory.make('Handler::Unset', item).execute(
51
+ index: index % @bits_per_item,
52
+ size: item_bit_size
42
53
  )
43
54
  end
44
55
  end
45
56
 
57
+ def set(index)
58
+ self[index] = 1
59
+ end
60
+
61
+ def unset(index)
62
+ self[index] = 0
63
+ end
64
+
46
65
  def each_byte(&proc)
47
- res = decrease_items_size(@internal_array, 8, @bits_per_item)
66
+ res = decrease_items_size(@internal_array, BYTE, @bits_per_item)
48
67
  proc ? res.each { |byte| proc.call(byte) } : res.each
49
68
  end
50
69
 
@@ -59,7 +78,7 @@ class Bitary
59
78
  end
60
79
 
61
80
  def bits_per_item=(value)
62
- raise ArgumentError unless [8, 16, 32, 64].include?(value)
81
+ raise ArgumentError unless [BYTE, SHORT, INT, LONG].include?(value)
63
82
 
64
83
  @internal_array =
65
84
  if value > @bits_per_item
@@ -110,29 +129,9 @@ class Bitary
110
129
  index / @bits_per_item
111
130
  end
112
131
 
113
- def compute_relative_offset(index, size)
114
- size - (index % @bits_per_item) - 1
115
- end
116
-
117
- def set_bit(value, offset)
118
- value | (2**offset)
119
- end
120
-
121
- def unset_bit(value, offset, size)
122
- value & (((2**size) - 1) - (2**offset))
123
- end
124
-
125
- def get_bit(value, offset)
126
- (value >> offset) & 0x1
127
- end
128
-
129
- def append_bits(value, offset, bits)
130
- (value << offset) | bits
131
- end
132
-
133
132
  def increase_items_size(array, new_size, bpi)
134
133
  processed_bits = 0
135
- array.each_with_object([0]) do |item, acc|
134
+ array.each_with_object([0]) do |value, acc|
136
135
  offset = bpi
137
136
  if processed_bits >= new_size
138
137
  offset = 0
@@ -140,7 +139,10 @@ class Bitary
140
139
  processed_bits = 0
141
140
  end
142
141
 
143
- acc[-1] = append_bits(acc[-1], offset, item)
142
+ acc[-1] = Factory.make('Handler::Append', acc[-1]).execute(
143
+ offset:,
144
+ value:
145
+ )
144
146
  processed_bits += bpi
145
147
  end
146
148
  end
@@ -165,5 +167,4 @@ class Bitary
165
167
  end
166
168
 
167
169
  alias at []
168
- alias set []=
169
170
  end
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.1
4
+ version: 0.1.3
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-26 00:00:00.000000000 Z
11
+ date: 2024-03-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby-based implementation of the bit array data structure
14
14
  email:
@@ -24,6 +24,14 @@ files:
24
24
  - README.md
25
25
  - Rakefile
26
26
  - lib/bitary.rb
27
+ - lib/bitary/deptainer.rb
28
+ - lib/bitary/factory.rb
29
+ - lib/bitary/handler.rb
30
+ - lib/bitary/handler/append.rb
31
+ - lib/bitary/handler/get.rb
32
+ - lib/bitary/handler/set.rb
33
+ - lib/bitary/handler/unset.rb
34
+ - lib/bitary/size.rb
27
35
  - lib/bitary/version.rb
28
36
  - sig/bitary.rbs
29
37
  homepage: https://github.com/Patacode/bitary