Module: FDB::Tuple

Defined in:
lib/fdbtuple.rb

Defined Under Namespace

Classes: SingleFloat, UUID

Constant Summary collapse

@@size_limits =
(0..8).map {|x| (1 << (x*8)) - 1}
@@NULL_CODE =

Type codes

0x00
@@BYTES_CODE =
0x01
@@STRING_CODE =
0x02
@@NESTED_CODE =
0x05
@@INT_ZERO_CODE =
0x14
@@POS_INT_END =
0x1c
@@NEG_INT_START =
0x0c
@@FLOAT_CODE =
0x20
@@DOUBLE_CODE =
0x21
@@FALSE_CODE =
0x26
@@TRUE_CODE =
0x27
@@UUID_CODE =
0x30

Class Method Summary collapse

Class Method Details

._code_for(v) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/fdbtuple.rb', line 239

def self._code_for(v)
  if v.nil?
    @@NULL_CODE
  elsif v.kind_of? String
    if v.encoding == Encoding::BINARY || v.encoding == Encoding::ASCII
      @@BYTES_CODE
    elsif v.encoding == Encoding::UTF_8
      @@STRING_CODE
    else
      raise ArgumentError, "unsupported encoding #{v.encoding.name}"
    end
  elsif v.kind_of? Integer
     @@INT_ZERO_CODE
  elsif v.kind_of? TrueClass
    @@TRUE_CODE
  elsif v.kind_of? FalseClass
    @@FALSE_CODE
  elsif v.kind_of? SingleFloat
    @@FLOAT_CODE
  elsif v.kind_of? Float
    @@DOUBLE_CODE
  elsif v.kind_of? UUID
    @@UUID_CODE
  elsif v.kind_of? Array
    @@NESTED_CODE
  else
    raise ArgumentError, "unsupported type #{v.class}"
  end
end

._compare_elems(v1, v2) ⇒ Object



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/fdbtuple.rb', line 281

def self._compare_elems(v1, v2)
  c1 = _code_for(v1)
  c2 = _code_for(v2)
  return c1 <=> c2 unless c1 == c2

  if c1 == @@NULL_CODE
    0
  elsif c1 == @@DOUBLE_CODE
    _compare_floats(v1, v2, true)
  elsif c1 == @@NESTED_CODE
    compare(v1, v2) # recurse
  else
    v1 <=> v2
  end
end

._compare_floats(f1, f2, is_double) ⇒ Object



269
270
271
272
273
274
275
276
277
278
279
# File 'lib/fdbtuple.rb', line 269

def self._compare_floats(f1, f2, is_double)
  # This converts the floats to their byte representation and then
  # does the comparison. Why?
  #   1) NaN comparison - Ruby doesn't really do this
  #   2) -0.0 == 0.0 in Ruby but not in our representation
  # It would be better to just take the floats and compare them, but
  # this way handles the edge cases correctly.
  b1 = float_adjust([f1].pack(is_double ? ">G" : ">g"), 0, (is_double ? 8 : 4), true)
  b2 = float_adjust([f2].pack(is_double ? ">G" : ">g"), 0, (is_double ? 8 : 4), true)
  b1 <=> b2
end

.compare(tuple1, tuple2) ⇒ Object



297
298
299
300
301
302
303
304
305
# File 'lib/fdbtuple.rb', line 297

def self.compare(tuple1, tuple2)
  i = 0
  while i < tuple1.length && i < tuple2.length
    c = self._compare_elems(tuple1[i], tuple2[i])
    return c unless c == 0
    i += 1
  end
  tuple1.length <=> tuple2.length
end

.pack(t) ⇒ Object



213
214
215
216
217
218
219
220
221
# File 'lib/fdbtuple.rb', line 213

def self.pack(t)
  (t.each_with_index.map {|el, i|
     begin
       (encode el).force_encoding("BINARY")
     rescue
       raise $!, "#{$!} at index #{i}", $!.backtrace
     end
   }).join
end

.range(tuple = []) ⇒ Object



234
235
236
237
# File 'lib/fdbtuple.rb', line 234

def self.range(tuple=[])
  p = pack(tuple)
  [p+"\x00", p+"\xFF"]
end

.unpack(key) ⇒ Object



223
224
225
226
227
228
229
230
231
232
# File 'lib/fdbtuple.rb', line 223

def self.unpack(key)
  key = key.dup.force_encoding("BINARY")
  pos = 0
  res = []
  while pos < key.length
    r, pos = decode(key, pos)
    res << r
  end
  res
end