class SnowFlake::ID
example SnowFlake::ID.new
(1,1).next_id
Attributes
datacenter_id[RW]
datacenter_id_bits[RW]
datacenter_id_shift[RW]
last_timestamp[RW]
max_datacenter_id[RW]
max_worker_id[RW]
sequence[RW]
sequence_bits[RW]
sequence_mask[RW]
timestamp_left_shift[RW]
twepoch[RW]
worker_id[RW]
worker_id_bits[RW]
worker_id_shift[RW]
Public Class Methods
new(worker_id, datacenter_id)
click to toggle source
@param worker_id
工作ID (0~31) @param datacenter_id
数据中心ID (0~31)
# File lib/snow_flake.rb, line 24 def initialize(worker_id, datacenter_id) self.twepoch = 1420041600000 # start time (2015-01-01) self.worker_id_bits = 5 # worker id bits self.datacenter_id_bits = 5 # datacenter id bits # Supported maximum worker id, resulting in 31 self.max_worker_id = -1 ^ (-1 << worker_id_bits) # Supported maximum datacenter id, resulting in 31 self.max_datacenter_id = -1 ^ (-1 << datacenter_id_bits) self.sequence_bits = 12 # The number of sequences in ID # The machine ID moves to the left 12 bits. self.worker_id_shift = sequence_bits # The data identification ID moves to the left 17 bits (12+5) self.datacenter_id_shift = sequence_bits + worker_id_bits # The time is shifted to the left by 22 bits(5+5+12) self.timestamp_left_shift = sequence_bits + worker_id_bits + datacenter_id_bits # The mask of generating sequence is 4095 (0b111111111111=0xfff=4095) self.sequence_mask = -1 ^ (-1 << sequence_bits) self.sequence = 0 # Millisecond sequence(0~4095) self.last_timestamp = -1 # Last timestamp of ID generation if worker_id > max_worker_id || worker_id < 0 raise "worker Id can't be greater than #{max_worker_id} or less than 0" end if datacenter_id > max_datacenter_id || datacenter_id < 0 raise "datacenter Id can't be greater than #{max_datacenter_id} or less than 0" end self.worker_id = worker_id # worker ID(0~31) self.datacenter_id = datacenter_id # datacenter ID(0~31) end
Public Instance Methods
next_id()
click to toggle source
# File lib/snow_flake.rb, line 53 def next_id timestamp = time_gen if timestamp < last_timestamp raise "Clock moved backwards. Refusing to generate id for #{last_timestamp - timestamp} milliseconds" end if last_timestamp == timestamp self.sequence = (sequence + 1) & sequence_mask timestamp = till_next_millis(last_timestamp) if sequence.zero? else self.sequence = 0 end self.last_timestamp = timestamp ((timestamp - twepoch) << timestamp_left_shift) | (datacenter_id << datacenter_id_shift) | (worker_id << worker_id_shift) | sequence end
till_next_millis(last_timestamp)
click to toggle source
# File lib/snow_flake.rb, line 68 def till_next_millis(last_timestamp) timestamp = time_gen timestamp = time_gen while timestamp <= last_timestamp timestamp end
time_gen()
click to toggle source
# File lib/snow_flake.rb, line 74 def time_gen (Time.now.to_f * 1000).floor end