class AnyFlake
Pure ruby independent ID generator like the SnowFlake, ChiliFlake. @see github.com/twitter/snowflake @see github.com/ma2shita/chiliflake
Constants
- MAX_NODE_ID
- MAX_SEQUENCE
- NODE_ID_BITS
- SEQUENCE_BITS
- TIMESTAMP_BITS
Public Class Methods
new(target_epoch, node_id, sequence = 0)
click to toggle source
# File lib/anyflake.rb, line 19 def initialize(target_epoch, node_id, sequence = 0) raise OverflowError, "invalid node_id (#{node_id} >= #{MAX_NODE_ID})" if node_id >= MAX_NODE_ID raise OverflowError, "invalid sequence (#{sequence} >= #{MAX_SEQUENCE})" if sequence >= MAX_SEQUENCE @target_epoch = target_epoch @node_id = node_id % MAX_NODE_ID @sequence = sequence % MAX_SEQUENCE @last_time = current_time end
parse(flake_id, target_epoch)
click to toggle source
# File lib/anyflake.rb, line 50 def self.parse(flake_id, target_epoch) hash = {} hash[:epoch_time] = flake_id >> (SEQUENCE_BITS + NODE_ID_BITS) hash[:time] = Time.at((hash[:epoch_time] + target_epoch) / 1000.0) hash[:node_id] = (flake_id >> SEQUENCE_BITS).to_s(2)[-NODE_ID_BITS, NODE_ID_BITS].to_i(2) hash[:sequence] = flake_id.to_s(2)[-SEQUENCE_BITS, SEQUENCE_BITS].to_i(2) hash end
Public Instance Methods
next_id()
click to toggle source
# File lib/anyflake.rb, line 28 def next_id time = current_time raise InvalidSystemClockError, "(#{time} < #{@last_time})" if time < @last_time if time == @last_time @sequence = (@sequence + 1) % MAX_SEQUENCE # NOTE: Distributed in node_id so if more than MAX_SEQUENCE, or wait until the next time. # time = till_next_time if @sequence == 0 else @sequence = 0 end @last_time = time compose(@last_time, @node_id, @sequence) end
parse(flake_id)
click to toggle source
# File lib/anyflake.rb, line 46 def parse(flake_id) AnyFlake.parse(flake_id, @target_epoch) end
Private Instance Methods
compose(last_time, node_id, sequence)
click to toggle source
# File lib/anyflake.rb, line 61 def compose(last_time, node_id, sequence) ((last_time - @target_epoch) << (SEQUENCE_BITS + NODE_ID_BITS)) + (node_id << SEQUENCE_BITS) + sequence end
current_time()
click to toggle source
# File lib/anyflake.rb, line 67 def current_time Time.now.strftime('%s%L').to_i end