Class: NBitArray

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/nbitarray.rb,
lib/nbitarray/version.rb

Constant Summary collapse

MARSHAL_SPLIT_SIZE =
512
VERSION =
"0.0.2"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bit) ⇒ NBitArray

Returns a new instance of NBitArray.



8
9
10
11
12
# File 'lib/nbitarray.rb', line 8

def initialize(bit)
  @bit = bit
  @bit_array = 0
  @mask = (1 << @bit) - 1
end

Instance Attribute Details

#bitObject (readonly)

Returns the value of attribute bit.



5
6
7
# File 'lib/nbitarray.rb', line 5

def bit
  @bit
end

Instance Method Details

#[](index) ⇒ Object



60
61
62
63
64
65
66
67
# File 'lib/nbitarray.rb', line 60

def [](index)
  bit_index = index * @bit

  # 10 10 11 00 >> 4          shift
  # 00 00 10 10 | 00 00 00 11 mask
  # 00 00 00 10               value
  (@bit_array >> bit_index) & @mask
end

#[]=(index, value) ⇒ Object

Raises:

  • (ArgumentError)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/nbitarray.rb', line 39

def []=(index, value)
  raise ArgumentError, 'too large value' if value >= 1 << @bit
  raise ArgumentError, 'value must be positive' if value < 0
  bit_index = index * @bit

  # 00 00 00 10 << 4 shift
  # 00 10 00 00
  assign_value = value << bit_index

  # 00 00 00 11 mask
  # 00 11 00 00 move to masking position
  # 11 00 11 11 reverse mask
  reverse_mask = ~(@mask << bit_index)

  # 10 01 11 00 & 11 00 11 11 erase current value by reverse mask
  # 10 00 11 00 | 00 10 00 00 assign new value
  # 10 10 11 00
  @bit_array = (@bit_array & reverse_mask) | assign_value
  value
end

#each(&block) ⇒ Object



35
36
37
# File 'lib/nbitarray.rb', line 35

def each(&block)
  size.times {|index| yield self[index] }
end

#marshal_dumpObject



69
70
71
# File 'lib/nbitarray.rb', line 69

def marshal_dump
  [@bit, @mask, splitted_bit_array(@bit_array, MARSHAL_SPLIT_SIZE), MARSHAL_SPLIT_SIZE]
end

#marshal_load(array) ⇒ Object



73
74
75
76
# File 'lib/nbitarray.rb', line 73

def marshal_load(array)
  @bit, @mask, splitted_array, split_size = array
  @bit_array = joined_bit_array(splitted_array, split_size)
end

#sizeObject Also known as: length



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/nbitarray.rb', line 14

def size
  if @bit_array == 0
    1
  else
    num_of_bits = Math.log2(@bit_array)
    if num_of_bits == Float::INFINITY
      # FIXME: this algorithm is too slow
      count = 1
      value = @bit_array
      while (value = value >> 1) != 0
        count += 1
      end
      num_of_bits = count
    else
      num_of_bits = num_of_bits.floor + 1
    end
    (num_of_bits - 1) / @bit + 1
  end
end