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 +4 -4
- data/CHANGELOG.md +11 -1
- data/README.md +6 -4
- data/lib/bitary/deptainer.rb +27 -0
- data/lib/bitary/factory.rb +27 -0
- data/lib/bitary/handler/append.rb +20 -0
- data/lib/bitary/handler/get.rb +22 -0
- data/lib/bitary/handler/set.rb +22 -0
- data/lib/bitary/handler/unset.rb +22 -0
- data/lib/bitary/handler.rb +22 -0
- data/lib/bitary/size.rb +10 -0
- data/lib/bitary/version.rb +1 -1
- data/lib/bitary.rb +36 -35
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc3397b948d902fe5cba56205955a01b7ad9f0d5d6eb7a1bf74984005f693114
|
4
|
+
data.tar.gz: af6673d27575273094dc34a4c67c67fbaa603de8a4e04375b0719e247f8cbcd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e44836498539b643e9b75ead2d63c9b91beda96008bc11d5e10a3b354d67ad4f604b1ceee4740665c60a7eeca7ca898e3f05b22aa48d2845f10fa71914a22998
|
7
|
+
data.tar.gz: 2cc01a7ba3ab7463ab64283fb6e4f82ab8dab61865595f93bbea1efdbf966463008faf2d9dab42f8e304e1f9e6bfa57d597b7d1826ef8521e7f480d2749403f1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
|
-
## [
|
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
|
data/lib/bitary/size.rb
ADDED
data/lib/bitary/version.rb
CHANGED
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:
|
9
|
-
raise ArgumentError unless [
|
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
|
-
|
27
|
+
item = @internal_array[item_index]
|
22
28
|
|
23
|
-
|
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
|
-
|
41
|
+
item = @internal_array[item_index]
|
33
42
|
|
34
43
|
@internal_array[item_index] =
|
35
44
|
if bit == 1
|
36
|
-
|
45
|
+
Factory.make('Handler::Set', item).execute(
|
46
|
+
index: index % @bits_per_item,
|
47
|
+
size: item_bit_size
|
48
|
+
)
|
37
49
|
else
|
38
|
-
|
39
|
-
@
|
40
|
-
|
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,
|
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 [
|
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 |
|
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] =
|
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.
|
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-
|
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
|