Class: Cassandra::Uuid::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/cassandra/uuid/generator.rb

Overview

Note:

Instances of this class are absolutely not threadsafe. You should never share instances between threads.

A UUID generator.

This class can be used to genereate Apache Cassandra timeuuid and uuid values.

Instance Method Summary collapse

Constructor Details

#initialize(node_id = (SecureRandom.random_number(2**47) | 0x010000000000), clock_id = SecureRandom.random_number(65536), clock = Time) ⇒ Generator

Create a new UUID generator.

The clock ID and node ID components are set to random numbers when the generator is created. These are used for generation of time UUIDs only.

Parameters:

  • node_id (Integer) (defaults to: (SecureRandom.random_number(2**47) | 0x010000000000))

    an alternate node ID

  • clock_id (Integer) (defaults to: SecureRandom.random_number(65536))

    an alternate clock ID

  • clock (Object<#now>) (defaults to: Time)

    used to generate timeuuid from current time

Raises:

  • (ArgumentError)

    if clock doesn't respond to now



47
48
49
50
51
52
53
# File 'lib/cassandra/uuid/generator.rb', line 47

def initialize(node_id = (SecureRandom.random_number(2**47) | 0x010000000000), clock_id = SecureRandom.random_number(65536), clock = Time)
  raise ::ArgumentError, "invalid clock" unless clock.respond_to?(:now)

  @node_id  = Integer(node_id)
  @clock_id = Integer(clock_id)
  @clock    = clock
end

Instance Method Details

#at(time, jitter = SecureRandom.random_number(65536)) ⇒ Cassandra::TimeUuid #at(seconds_with_frac, jitter = SecureRandom.random_number(65536)) ⇒ Cassandra::TimeUuid #at(seconds, microseconds_with_frac, jitter = SecureRandom.random_number(65536)) ⇒ Cassandra::TimeUuid

Note:

the jitter argument accepted by all variants of this method is required to add randomness to generated TimeUuid and might affect the order of generated timestamps. You should set jitter to 0 when the source time(stamp)s are unique.

Returns a new UUID with a time component based on the specified Time. A piece of jitter is added to ensure that multiple calls with the same time do not generate the same UUID (if you want determinism you can set the second parameter to zero).

Examples:

Creating a TimeUuid from a Time instance

generator = Cassandra::Uuid::Generator.new
timeuuid  = generator.at(Time.at(1413582460))

puts timeuuid.to_time

# Outputs:
# 2014-10-17 21:47:40 UTC

Creating a TimeUuid from a timestamp

generator = Cassandra::Uuid::Generator.new
timeuuid  = generator.at(1413582423)

puts timeuuid.to_time

# Outputs:
# 2014-10-17 21:47:03 UTC

Avoid jitter in generated TimeUuid

timestamp = 1413582418
generator = Cassandra::Uuid::Generator.new
timeuuid  = generator.at(timestamp, 0)

puts timeuuid.to_time.to_i

# Outputs:
# 1413582418

Overloads:

  • #at(time, jitter = SecureRandom.random_number(65536)) ⇒ Cassandra::TimeUuid

    Returns a new UUID.

    Parameters:

    • time (Time)

      a Time instance

    • jitter (Integer) (defaults to: SecureRandom.random_number(65536))

      a number of microseconds to add to the time

    Returns:

  • #at(seconds_with_frac, jitter = SecureRandom.random_number(65536)) ⇒ Cassandra::TimeUuid

    Returns a new UUID.

    Parameters:

    • seconds_with_frac (Numeric)

      can be Integer, Float, Rational, or other Numeric

    • jitter (Integer) (defaults to: SecureRandom.random_number(65536))

      a number of microseconds to add to the time

    Returns:

  • #at(seconds, microseconds_with_frac, jitter = SecureRandom.random_number(65536)) ⇒ Cassandra::TimeUuid

    Returns a new UUID.

    Parameters:

    • seconds (Integer)
    • microseconds_with_frac (Numeric)

      can be Integer, Float, Rational, or other Numeric

    • jitter (Integer) (defaults to: SecureRandom.random_number(65536))

      a number of microseconds to add to the time

    Returns:

Raises:

  • (ArgumentError)

    when given no arguments or more than 3 arguments

See Also:

  • Time.at


152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/cassandra/uuid/generator.rb', line 152

def at(*args)
  raise ::ArgumentError, "not enough arguments" if args.empty?
  raise ::ArgumentError, "too many arguments"   if args.size > 3

  if args.first.is_a?(Time)
    time   = args.shift
    jitter = args.empty? ? SecureRandom.random_number(65536) : Integer(args.shift)
  else
    jitter = args.size > 2 ? Integer(args.pop) : SecureRandom.random_number(65536)
    time   = Time.at(*args)
  end

  from_usecs(time.to_i * 1_000_000 + time.usec + jitter)
end

#nowCassandra::TimeUuid

Returns a new UUID with a time component that is the current time.

If two calls to #now happen within the time afforded by the system clock resolution a counter is incremented and added to the time component.

If the clock moves backwards the clock ID is reset to a new random number.

Examples:

Creating a sequential TimeUuids for the current time

generator = Cassandra::Uuid::Generator.new
timeuuids = 5.times.map { generator.now }

puts timeuuids.zip(timeuuids.map(&:to_time)).map(&:inspect)

# Outputs:
# [8614b7d0-5646-11e4-8e54-6761d3995ef3, 2014-10-17 21:42:42 UTC]
# [8614b91a-5646-11e4-8e54-6761d3995ef3, 2014-10-17 21:42:42 UTC]
# [8614b960-5646-11e4-8e54-6761d3995ef3, 2014-10-17 21:42:42 UTC]
# [8614b99c-5646-11e4-8e54-6761d3995ef3, 2014-10-17 21:42:42 UTC]
# [8614b9ce-5646-11e4-8e54-6761d3995ef3, 2014-10-17 21:42:42 UTC]

Returns:

See Also:

  • Time.now


80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/cassandra/uuid/generator.rb', line 80

def now
  now   = @clock.now
  usecs = now.to_i * 1_000_000 + now.usec
  if @last_usecs && @last_usecs - @sequence <= usecs && usecs <= @last_usecs
    @sequence += 1
  elsif @last_usecs && @last_usecs > usecs
    @sequence = 0
    @clock_id = SecureRandom.random_number(65536)
  else
    @sequence = 0
  end
  @last_usecs = usecs + @sequence
  from_usecs(@last_usecs)
end

#uuidCassandra::Uuid

Returns a completely random version 4 UUID.

Examples:

Generating a random Uuid

generator = Cassandra::Uuid::Generator.new
uuid      = generator.uuid

puts uuid

# Outputs:
# 664dedae-e162-4bc0-9066-b9f1968252aa

Returns:

See Also:

  • SecureRandom.uuid


181
182
183
# File 'lib/cassandra/uuid/generator.rb', line 181

def uuid
  Uuid.new(SecureRandom.uuid)
end