Method: Corosync::CMAP#set_value

Defined in:
lib/corosync/cmap.rb

#set_value(name, value) ⇒ Number, String

Set a key to the specified value. A convenience wrapper around #set to automatically determine the type. If the value is numeric, we will use the same type as the existing value (if it already exists). Otherwise we pick the smallest type that will hold the value.

Parameters:

  • name (String)

    The name of the key

  • value (Number, String)

    The value to set

Returns:

  • (Number, String)

    The value as stored in the CMAP service. This will normally be the value passed in, but if you store a non-string as a string, the return will be the result of to_s



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/corosync/cmap.rb', line 168

def set_value(name, value)
  type = catch :type do
    # strings are strings
    throw :type, :string if value.is_a?(String)

    # try and get existing type
    begin
      type_ptr = FFI::MemoryPointer.new(Corosync.find_type(:cmap_value_types_t))
      size_ptr = FFI::MemoryPointer.new(:size_t)
      Corosync.cs_send(:cmap_get, @handle, name, nil, size_ptr, type_ptr)
      type = type_ptr.read_type(Corosync.find_type(:cmap_value_types_t))
      type = Corosync.enum_type(:cmap_value_types_t)[type]
      if SIZEMAP.keys.include(type) then
        size = size_ptr.read_type(:size_t)
        if size <= SIZEMAP[type].bytes then
          # it fits within the existing type
          throw :type, type
        end
        # it doesnt fit, we need to re-type it
      end
    rescue Corosync::NotExistError
    end

    # find the type that will fit
    if value.is_a?(Float) then
      type = :double
    elsif value.is_a?(Numeric) then
      if value.abs <= 2 ** 7 and value < 0 then
        type = :int8
      elsif value <= 2 ** 8 and value >= 0 then
        type = :uint8
      elsif value.abs <= 2 ** 15 and value < 0 then
        type = :int16
      elsif value <= 2 ** 16 and value >= 0 then
        type = :uint16
      elsif value.abs <= 2 ** 31 and value < 0 then
        type = :int32
      elsif value <= 2 ** 32 and value >= 0 then
        type = :uint32
      elsif value.abs <= 2 ** 63 and value < 0 then
        type = :int64
      elsif value < 2 ** 64 and value >= 0 then
        type = :uint64
      else
        raise ArgumentError, "Corosync cannot handle numbers larger than 64-bit"
      end

      throw :type, type
    end

    # Unknown type, force it into a string
    throw :type, :string
  end

  value = value.to_s if type == :string and !value.is_a?(String)

  set(name, type, value)
end