class AMQ::BitSet
Very minimalistic, pure Ruby implementation of bit set. Inspired by java.util.BitSet, although significantly smaller in scope.
Originally part of amqp gem. Extracted to make it possible for Bunny to use it.
Constants
- ADDRESS_BITS_PER_WORD
API
- BITS_PER_WORD
- WORD_MASK
Attributes
Public Class Methods
@param [Integer] Number of bits in the set @api public
# File lib/amq/bit_set.rb, line 20 def initialize(nbits) @nbits = nbits self.init_words(nbits) end
@private
# File lib/amq/bit_set.rb, line 92 def self.number_of_trailing_ones(num) 0.upto(BITS_PER_WORD) do |bit| return bit if num[bit] == 0 end BITS_PER_WORD end
Public Instance Methods
Clears all bits in the set @api public
# File lib/amq/bit_set.rb, line 65 def clear self.init_words(@nbits) end
Fetches flag value for given bit.
@param [Integer] A bit to fetch @return [Boolean] true if given bit is set, false otherwise @api public
# File lib/amq/bit_set.rb, line 42 def get(i) check_range(i) w = self.word_index(i) (@words[w] & (1 << i % BITS_PER_WORD)) != 0 end
# File lib/amq/bit_set.rb, line 69 def next_clear_bit() @words.each_with_index do |word, i| if word == WORD_MASK next end return i * BITS_PER_WORD + BitSet.number_of_trailing_ones(word) end -1 end
Sets (flags) given bit. This method allows bits to be set more than once in a row, no exception will be raised.
@param [Integer] A bit to set @api public
# File lib/amq/bit_set.rb, line 30 def set(i) check_range(i) w = self.word_index(i) result = @words[w] |= (1 << (i % BITS_PER_WORD)) result end
# File lib/amq/bit_set.rb, line 79 def to_s result = "" @words.each do |w| result += w.to_s(2).rjust(BITS_PER_WORD,'0') + ":" end result end
Unsets (unflags) given bit. This method allows bits to be unset more than once in a row, no exception will be raised.
@param [Integer] A bit to unset @api public
# File lib/amq/bit_set.rb, line 54 def unset(i) check_range(i) w = self.word_index(i) return if w.nil? result = @words[w] &= ~(1 << i % BITS_PER_WORD) result end
@private
# File lib/amq/bit_set.rb, line 100 def word_index(i) i >> ADDRESS_BITS_PER_WORD end
Protected Instance Methods
# File lib/amq/bit_set.rb, line 112 def check_range(i) if i < 0 || i >= @nbits raise IndexError.new("Cannot access bit #{i} from a BitSet with #{@nbits} bits") end end
@private
# File lib/amq/bit_set.rb, line 107 def init_words(nbits) n = word_index(nbits-1) + 1 @words = Array.new(n) { 0 } end