class Memcached #:stopdoc: def self.load_constants(prefix, hash = {}) Lib.constants.grep(/^#{prefix}/).each do |const_name| hash[const_name[prefix.length..-1].downcase.to_sym] = Lib.const_get(const_name) end hash end BEHAVIORS = load_constants("MEMCACHED_BEHAVIOR_") BEHAVIOR_VALUES = { false => 0, true => 1 } HASH_VALUES = {} BEHAVIOR_VALUES.merge!(load_constants("MEMCACHED_HASH_", HASH_VALUES)) DISTRIBUTION_VALUES = {} BEHAVIOR_VALUES.merge!(load_constants("MEMCACHED_DISTRIBUTION_", DISTRIBUTION_VALUES)) DIRECT_VALUE_BEHAVIORS = [:retry_timeout, :connect_timeout, :rcv_timeout, :socket_recv_size, :poll_timeout, :socket_send_size, :server_failure_limit] CONVERSION_FACTORS = { :rcv_timeout => 1_000_000, :poll_timeout => 1_000, :connect_timeout => 1_000 } #:startdoc: private # Set a behavior option for this Memcached instance. Accepts a Symbol behavior and either true, false, or a Symbol for value. Arguments are validated and converted into integers for the struct setter method. def set_behavior(behavior, value) #:doc: raise ArgumentError, "No behavior #{behavior.inspect}" unless b_id = BEHAVIORS[behavior] # Scoped validations; annoying msg = "Invalid behavior value #{value.inspect} for #{behavior.inspect}" case behavior when :hash then raise(ArgumentError, msg) unless HASH_VALUES[value] when :distribution then raise(ArgumentError, msg) unless DISTRIBUTION_VALUES[value] when *DIRECT_VALUE_BEHAVIORS then raise(ArgumentError, msg) unless value.is_a?(Numeric) and value >= 0 else raise(ArgumentError, msg) unless BEHAVIOR_VALUES[value] end lib_value = BEHAVIOR_VALUES[value] || (value * (CONVERSION_FACTORS[behavior] || 1)).to_i #STDERR.puts "Setting #{behavior}:#{b_id} => #{value} (#{lib_value})" Lib.memcached_behavior_set(@struct, b_id, lib_value) #STDERR.puts " -> set to #{get_behavior(behavior).inspect}" end # Get a behavior value for this Memcached instance. Accepts a Symbol. def get_behavior(behavior) raise ArgumentError, "No behavior #{behavior.inspect}" unless b_id = BEHAVIORS[behavior] value = Lib.memcached_behavior_get(@struct, b_id) if BEHAVIOR_VALUES.invert.has_key?(value) # False, nil are valid values so we can not rely on direct lookups case behavior # Scoped values; still annoying when :hash then HASH_VALUES.invert[value] when :distribution then DISTRIBUTION_VALUES.invert[value] else value end else value end end end