class Cql::TimeUuid::Generator
A UUID version 1, variant 1 generator. It can generate a sequence of UUIDs with reasonable uniqueness guarantees:
-
The clock ID and node ID components are set to random numbers when the generator is created.
-
If two calls to {#next} 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.
Instances of this class are absolutely not threadsafe. You should never share instances between threads.
Public Class Methods
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
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
@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
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