Class: Cql::TimeUuid::Generator
- Inherits:
-
Object
- Object
- Cql::TimeUuid::Generator
- Defined in:
- lib/cql/time_uuid.rb
Overview
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.
Instance Method Summary collapse
-
#from_time(time, jitter = rand(2**16)) ⇒ Cql::TimeUuid
Returns a new UUID with a time component based on the specified Time.
- #from_usecs(usecs) ⇒ Object
-
#initialize(node_id = nil, clock_id = nil, clock = Time) ⇒ Generator
constructor
Create a new UUID generator.
-
#next ⇒ Cql::TimeUuid
Returns a new UUID with a time component that is the current time.
Constructor Details
#initialize(node_id = nil, clock_id = nil, clock = Time) ⇒ Generator
Create a new UUID generator.
43 44 45 46 47 |
# File 'lib/cql/time_uuid.rb', line 43 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 |
Instance Method Details
#from_time(time, jitter = rand(2**16)) ⇒ Cql::TimeUuid
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).
77 78 79 80 |
# File 'lib/cql/time_uuid.rb', line 77 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) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/cql/time_uuid.rb', line 83 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 ⇒ Cql::TimeUuid
Returns a new UUID with a time component that is the current time.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/cql/time_uuid.rb', line 53 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 |