class Uuidx::Version6
UUID Version 6 defined by the RFC 4122 BIS-01 Draft.
To construct a new UUID v6 value create a generator, then use generate
.
g = Uuidx::Version6.new g.generate # => "1eda9761-9f6f-6414-8c5f-fd61f1239907"
The implementation will use SecureRandom
to populate the Node and Clock Sequence bits with a random value at module load time.
Generation is thread-safe, but if you are using multi-process clusters you should call reset!
at the start of each process to reduce the chance of two processes generating the same value.
If you have need to make sure that the clock resolution is sufficient for the v6 specification you can call ::verify_clock_resolution!
and handle the ClockResolutionError
as you see fit.
begin Uuidx::Version6.verify_clock_resolution! rescue Uuidx::ClockResolutionError # ... end
The necessary clock resolution for v6 is 100ns.
A Note on Clock Timings¶ ↑
To combat clock drift, leap-second smearing, and other clock value changes that can appear without requiring additional compute cost this implementation always increments the clock sequence number.
Public Class Methods
Construct a new UUID v6 generator.
# File lib/uuidx/version6.rb, line 48 def initialize reset! end
Verify that the clock resolution is capable of 100ns resolution.
Raises ClockResolutionError
when the clock resolution is insufficient.
# File lib/uuidx/version6.rb, line 73 def self.verify_clock_resolution! ns_res = Process.clock_getres(Process::CLOCK_REALTIME, :nanosecond) raise ClockResolutionError, "Detected #{ns_res}ns resolution, need <= 100ns" if ns_res > 100 true end
Public Instance Methods
Construct a UUID v6 value.
# File lib/uuidx/version6.rb, line 53 def generate @clock_sequence = (@clock_sequence + CLOCK_SEQ_INCREMENT) & CLOCK_SEQ_MASK ts = GREGORIAN_MICROSECOND_TENTHS + (Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond) / TS_NS_FACTOR) ts = ((ts << TS_MASK_SHIFT) & TS_HIGH_MID_MASK) | (ts & TS_LOW_MASK) Uuidx.format(VERSION_VARIANT | (ts << TS_POSITIONAL_SHIFT) | @clock_sequence | @node_id) end
Reset the generator with a new random node ID and clock sequence.
This method is not thread-safe and should only be called at application or child process start.
# File lib/uuidx/version6.rb, line 65 def reset! @node_id = (SecureRandom.bytes(8).unpack1("Q") & NODE_ID_MASK) | NODE_ID_MC_BIT @clock_sequence = SecureRandom.bytes(4).unpack1("L") << CLOCK_SEQ_SHIFT end