class Cql::TimeUuid::Generator

A UUID version 1, variant 1 generator. It can generate a sequence of UUIDs with reasonable uniqueness guarantees:

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

Public Class Methods

new(node_id=nil, clock_id=nil, clock=Time) click to toggle source

Create a new UUID generator.

@param [Integer] node_id an alternate node ID (defaults to a random number) @param [Integer] clock_id an alternate clock ID (defaults to a random number)

# File lib/cql/time_uuid.rb, line 63
def initialize(node_id=nil, clock_id=nil, clock=Time)
  @node_id = node_id || (rand(2**47) | 0x010000000000)
  @clock_id = clock_id || rand(2**16)
  @clock = clock
end

Public Instance Methods

from_time(time, jitter=rand(2**16)) click to toggle source

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).

@param [Time] time the time to encode into the UUID @param [Integer] jitter a number of microseconds to add to the time to make it unique @return [Cql::TimeUuid] a new UUID

# File lib/cql/time_uuid.rb, line 97
def from_time(time, jitter=rand(2**16))
  usecs = time.to_i * 1_000_000 + time.usec + jitter
  from_usecs(usecs)
end
from_usecs(usecs) click to toggle source

@private

# File lib/cql/time_uuid.rb, line 103
def from_usecs(usecs)
  t = GREGORIAN_OFFSET + usecs * 10
  time_hi  = t & 0x0fff000000000000
  time_mid = t & 0x0000ffff00000000
  time_low = t & 0x00000000ffffffff
  version = 1
  clock_id = @clock_id & 0x3fff
  node_id = @node_id & 0xffffffffffff
  variant = 0x8000
  n = (time_low << 96) | (time_mid << 48) | (time_hi << 16)
  n |= version << 76
  n |= (clock_id | variant) << 48
  n |= node_id
  TimeUuid.new(n)
end
next() click to toggle source

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

@return [Cql::TimeUuid] a new UUID

# File lib/cql/time_uuid.rb, line 73
def next
  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 = rand(2**16)
  else
    @sequence = 0
  end
  @last_usecs = usecs + @sequence
  from_usecs(@last_usecs)
end