Class: Cassandra::UUID

Inherits:
Comparable show all
Defined in:
lib/cassandra/uuid.rb

Overview

UUID format version 1, as specified in RFC 4122, with jitter in place of the mac address and sequence counter.

Defined Under Namespace

Classes: InvalidVersion

Constant Summary collapse

GREGORIAN_EPOCH_OFFSET =

Oct 15, 1582

0x01B2_1DD2_1381_4000
VARIANT =
0b1000_0000_0000_0000

Instance Method Summary collapse

Methods inherited from Comparable

#==, #eql?, #hash, #to_s

Constructor Details

#initialize(bytes = nil) ⇒ UUID

Returns a new instance of UUID.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/cassandra/uuid.rb', line 14

def initialize(bytes = nil)
  case bytes
  when self.class # UUID
    @bytes = bytes.to_s
  when String
    case bytes.size
    when 16 # Raw byte array
      @bytes = bytes
    when 36 # Human-readable UUID representation; inverse of #to_guid
      elements = bytes.split("-")
      raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (malformed UUID representation)" if elements.size != 5
      @bytes = elements.join.to_a.pack('H32')
    else
      raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (invalid bytecount)"
    end

  when Integer
    raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (integer out of range)" if bytes < 0 or bytes > 2**128
    @bytes = [
      (bytes >> 96) & 0xFFFF_FFFF,
      (bytes >> 64) & 0xFFFF_FFFF,
      (bytes >> 32) & 0xFFFF_FFFF,
      bytes & 0xFFFF_FFFF
    ].pack("NNNN")

  when NilClass, Time
    time = (bytes || Time).stamp * 10 + GREGORIAN_EPOCH_OFFSET
    # See http://github.com/spectra/ruby-uuid/
    @bytes = [
      time & 0xFFFF_FFFF,
      time >> 32,
      ((time >> 48) & 0x0FFF) | 0x1000,
      # Top 3 bytes reserved
      rand(2**13) | VARIANT,
      rand(2**16),
      rand(2**32)
    ].pack("NnnnnN")

  else
    raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (unknown source class)"
  end
end

Instance Method Details

#<=>(other) ⇒ Object



90
91
92
# File 'lib/cassandra/uuid.rb', line 90

def <=>(other)
  total_usecs <=> other.send(:total_usecs)
end

#inspect(long = false) ⇒ Object



94
95
96
97
98
99
100
101
102
# File 'lib/cassandra/uuid.rb', line 94

def inspect(long = false)
  "<Cassandra::UUID##{object_id} time: #{
    Time.at(seconds).inspect
  }, usecs: #{
    usecs
  } jitter: #{
    @bytes.unpack('QQ')[1]
  }" + (long ? ", version: #{version}, variant: #{variant}, guid: #{to_guid}>" :  ">")
end

#secondsObject



82
83
84
# File 'lib/cassandra/uuid.rb', line 82

def seconds
  total_usecs / 1_000_000
end

#to_guidObject



75
76
77
78
79
80
# File 'lib/cassandra/uuid.rb', line 75

def to_guid
  elements = @bytes.unpack("NnnCCa6")
  node = elements[-1].unpack('C*')
  elements[-1] = '%02x%02x%02x%02x%02x%02x' % node
  "%08x-%04x-%04x-%02x%02x-%s" % elements
end

#to_iObject



57
58
59
60
61
62
63
# File 'lib/cassandra/uuid.rb', line 57

def to_i
  ints = @bytes.unpack("NNNN")
  (ints[0] << 96) +
  (ints[1] << 64) +
  (ints[2] << 32) +
  ints[3]
end

#usecsObject



86
87
88
# File 'lib/cassandra/uuid.rb', line 86

def usecs
  total_usecs % 1_000_000
end

#variantObject



71
72
73
# File 'lib/cassandra/uuid.rb', line 71

def variant
  @bytes.unpack('QnnN')[1] >> 13
end

#versionObject



65
66
67
68
69
# File 'lib/cassandra/uuid.rb', line 65

def version
  time_high = @bytes.unpack("NnnQ")[2]
  version = (time_high & 0xF000).to_s(16)[0].chr.to_i
  version > 0 and version < 6 ? version : -1
end