Class: Hyperll::RegisterSet

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Util
Defined in:
lib/hyperll/register_set.rb

Constant Summary collapse

LOG2_BITS_PER_WORD =
6
REGISTER_SIZE =
5

Constants included from Util

Util::INTEGER_SIZE, Util::INT_MASK, Util::POWERS_OF_TWO

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

#number_of_leading_zeros

Constructor Details

#initialize(count, values = nil) ⇒ RegisterSet

Returns a new instance of RegisterSet.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/hyperll/register_set.rb', line 13

def initialize(count, values = nil)
  @count = count

  @bits = count / LOG2_BITS_PER_WORD
  if @bits.zero?
    @size = 1
  elsif (@bits % INTEGER_SIZE).zero?
    @size = @bits
  else
    @size = @bits + 1
  end

  @values = values || Array.new(@size, 0)
end

Instance Attribute Details

#countObject (readonly)

Returns the value of attribute count.



11
12
13
# File 'lib/hyperll/register_set.rb', line 11

def count
  @count
end

#sizeObject (readonly)

Returns the value of attribute size.



11
12
13
# File 'lib/hyperll/register_set.rb', line 11

def size
  @size
end

Instance Method Details

#[](position) ⇒ Object



36
37
38
39
40
41
# File 'lib/hyperll/register_set.rb', line 36

def [](position)
  bucket = position / LOG2_BITS_PER_WORD
  shift = REGISTER_SIZE * (position - (bucket * LOG2_BITS_PER_WORD))

  return (@values[bucket] & (0x1f * POWERS_OF_TWO[shift])) / POWERS_OF_TWO[shift]
end

#[]=(position, value) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/hyperll/register_set.rb', line 28

def []=(position, value)
  bucket = position / LOG2_BITS_PER_WORD
  shift = REGISTER_SIZE * (position - (bucket * LOG2_BITS_PER_WORD))

  @values[bucket] = ((@values[bucket] & ~(0x1f * POWERS_OF_TWO[shift])) | (value * POWERS_OF_TWO[shift]))
  @values[bucket] &= INT_MASK if @values[bucket] > INT_MASK
end

#eachObject



43
44
45
46
47
48
# File 'lib/hyperll/register_set.rb', line 43

def each
  return enum_for(:each) unless block_given?
  @count.times do |i|
    yield self[i]
  end
end

#merge(other) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/hyperll/register_set.rb', line 66

def merge(other)
  @size.times do |bucket|
    word = 0
    LOG2_BITS_PER_WORD.times do |j|
      mask = 0x1f << (REGISTER_SIZE * j);

      this_val = self.values[bucket] & mask
      other_val = other.values[bucket] & mask
      word |= [this_val, other_val].max
    end

    @values[bucket] = word
  end
end

#serializeObject



81
82
83
# File 'lib/hyperll/register_set.rb', line 81

def serialize
  @values.pack("N*")
end

#update_if_greater(position, value) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/hyperll/register_set.rb', line 50

def update_if_greater(position, value)
  bucket = position / LOG2_BITS_PER_WORD
  shift = REGISTER_SIZE * (position - (bucket * LOG2_BITS_PER_WORD));
  mask = (0x1f * POWERS_OF_TWO[shift])

  current_value = @values[bucket] & mask
  new_value = value * POWERS_OF_TWO[shift]
  if current_value < new_value
    @values[bucket] = ((@values[bucket] & ~mask) | new_value)
    @values[bucket] &= INT_MASK if @values[bucket] > INT_MASK
    true
  else
    false
  end
end