This repository has been archived by the owner on Sep 11, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:ruby-amqp/amqp
- Loading branch information
Showing
12 changed files
with
25 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,3 +14,4 @@ vendor | |
.yardoc/* | ||
doc/* | ||
tmp/* | ||
bin/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,80 +1,9 @@ | ||
# encoding: utf-8 | ||
|
||
module AMQP | ||
# Very minimalistic, pure Ruby implementation of bit set. Inspired by java.util.BitSet, | ||
# although significantly smaller in scope. | ||
class BitSet | ||
|
||
# | ||
# API | ||
# | ||
|
||
ADDRESS_BITS_PER_WORD = 6 | ||
BITS_PER_WORD = (1 << ADDRESS_BITS_PER_WORD) | ||
WORD_MASK = 0xffffffffffffffff | ||
|
||
# @param [Integer] Number of bits in the set | ||
# @api public | ||
def initialize(nbits) | ||
@nbits = nbits | ||
|
||
self.init_words(nbits) | ||
end # initialize(nbits) | ||
|
||
# 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 | ||
def set(i) | ||
w = self.word_index(i) | ||
@words[w] |= (1 << i) | ||
end # set(i) | ||
|
||
# Fetches flag value for given bit. | ||
# | ||
# @param [Integer] A bit to fetch | ||
# @return [Boolean] true if given bit is set, false otherwise | ||
# @api public | ||
def get(i) | ||
w = self.word_index(i) | ||
|
||
(@words[w] & (1 << i)) != 0 | ||
end # get(i) | ||
alias [] get | ||
require "amq/bit_set" | ||
|
||
# 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 | ||
def unset(i) | ||
w = self.word_index(i) | ||
return if w.nil? | ||
|
||
@words[w] &= ~(1 << i) | ||
end # unset(i) | ||
|
||
# Clears all bits in the set | ||
# @api public | ||
def clear | ||
self.init_words(@nbits) | ||
end # clear | ||
|
||
|
||
# | ||
# Implementation | ||
# | ||
|
||
protected | ||
|
||
# @private | ||
def init_words(nbits) | ||
n = word_index(nbits-1) + 1 | ||
@words = Array.new(n) { 1 } | ||
end # init_words | ||
|
||
# @private | ||
def word_index(i) | ||
i >> ADDRESS_BITS_PER_WORD | ||
end # word_index(i) | ||
end # BitSet | ||
module AMQP | ||
# A forward reference for AMQP::BitSet that was extracted to amq-protocol | ||
# to make it possible to reuse it in Bunny. | ||
BitSet = AMQ::BitSet | ||
end # AMQP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,9 @@ | ||
# encoding: utf-8 | ||
|
||
require "amqp/bit_set" | ||
require "amq/int_allocator" | ||
|
||
module AMQP | ||
# 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. | ||
class IntAllocator | ||
|
||
# | ||
# API | ||
# | ||
|
||
# @return [Integer] Number of integers in the allocation range | ||
attr_reader :number_of_bits | ||
# @return [Integer] Upper boundary of the integer range available for allocation | ||
attr_reader :hi | ||
# @return [Integer] Lower boundary of the integer range available for allocation | ||
attr_reader :lo | ||
|
||
# @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 | ||
def initialize(lo, hi) | ||
raise ArgumentError.new "upper boundary must be greater than the lower one (given: hi = #{hi}, lo = #{lo})" unless hi > lo | ||
|
||
@hi = hi | ||
@lo = lo | ||
|
||
@number_of_bits = hi - lo | ||
@range = Range.new(1, @number_of_bits) | ||
@free_set = BitSet.new(@number_of_bits) | ||
end # initialize(hi, lo) | ||
|
||
# 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. | ||
def allocate | ||
if n = find_unallocated_position | ||
@free_set.set(n) | ||
|
||
n | ||
else | ||
-1 | ||
end | ||
end # allocate | ||
|
||
# Releases previously allocated integer. If integer provided as argument was not previously allocated, | ||
# this method has no effect. | ||
# | ||
# @return [NilClass] nil | ||
def free(reservation) | ||
@free_set.unset(reservation) | ||
end # free(reservation) | ||
alias release free | ||
|
||
# @return [Boolean] true if provided argument was previously allocated, false otherwise | ||
def allocated?(reservation) | ||
@free_set.get(reservation) | ||
end # allocated?(reservation) | ||
|
||
# Releases the whole allocation range | ||
def reset | ||
@free_set.clear | ||
end # reset | ||
|
||
|
||
|
||
protected | ||
|
||
# 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 | ||
def find_unallocated_position | ||
r = nil | ||
@range.each do |i| | ||
if !@free_set.get(i) | ||
r = i | ||
break; | ||
end | ||
end | ||
|
||
r | ||
end # find_unallocated_position | ||
end # IntAllocator | ||
# A forward reference for AMQP::IntAllocator that was extracted to amq-protocol | ||
# to make it possible to reuse it in Bunny. | ||
IntAllocator = AMQ::IntAllocator | ||
end # AMQP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters