bitary 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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