Object
Simple bitset-based integer allocator, heavily inspired by com.rabbitmq.utility.IntAllocator class in the RabbitMQ Java client.
Unlike monotonically incrementing identifier, this allocator is suitable for very long running programs that aggressively allocate and release channels.
@param [Integer] lo Lower boundary of the integer range available for allocation @param [Integer] hi Upper boundary of the integer range available for allocation @raise [ArgumentError] if upper boundary is not greater than the lower one
# File lib/amqp/int_allocator.rb, line 27 27: def initialize(lo, hi) 28: raise ArgumentError.new "upper boundary must be greater than the lower one (given: hi = #{hi}, lo = #{lo})" unless hi > lo 29: 30: @hi = hi 31: @lo = lo 32: 33: @number_of_bits = hi - lo 34: @range = Range.new(1, @number_of_bits) 35: @free_set = BitSet.new(@number_of_bits) 36: end
Attempts to allocate next available integer. If allocation succeeds, allocated value is returned. Otherwise, nil is returned.
Current implementation of this method is O(n), where n is number of bits in the range available for allocation.
@return [Integer] Allocated integer if allocation succeeded. nil otherwise.
# File lib/amqp/int_allocator.rb, line 45 45: def allocate 46: if n = find_unallocated_position 47: @free_set.set(n) 48: 49: n 50: else 51: 1 52: end 53: end
@return [Boolean] true if provided argument was previously allocated, false otherwise
# File lib/amqp/int_allocator.rb, line 65 65: def allocated?(reservation) 66: @free_set.get(reservation) 67: end
Releases previously allocated integer. If integer provided as argument was not previously allocated, this method has no effect.
@return [NilClass] nil
# File lib/amqp/int_allocator.rb, line 59 59: def free(reservation) 60: @free_set.unset(reservation) 61: end
This implementation is significantly less efficient that what the RabbitMQ Java client has (based on java.lang.Long#nextSetBit and java.lang.Long.numberOfTrailingZeros, and thus binary search over bits). But for channel id generation, this is a good enough implementation.
@private
# File lib/amqp/int_allocator.rb, line 84 84: def find_unallocated_position 85: r = nil 86: @range.each do |i| 87: if !@free_set.get(i) 88: r = i 89: break; 90: end 91: end 92: 93: r 94: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.