Class: AnyFlake
- Inherits:
-
Object
- Object
- AnyFlake
- Defined in:
- lib/anyflake.rb
Overview
Pure ruby independent ID generator like the SnowFlake, ChiliFlake.
Defined Under Namespace
Classes: InvalidSystemClockError, OverflowError
Constant Summary collapse
- TIMESTAMP_BITS =
41- NODE_ID_BITS =
10- SEQUENCE_BITS =
12- MAX_NODE_ID =
1024
(1 << NODE_ID_BITS)
- MAX_SEQUENCE =
4096
(1 << SEQUENCE_BITS)
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(target_epoch, node_id, sequence = 0) ⇒ AnyFlake
constructor
A new instance of AnyFlake.
- #next_id ⇒ Object
- #parse(flake_id) ⇒ Object
Constructor Details
#initialize(target_epoch, node_id, sequence = 0) ⇒ AnyFlake
Returns a new instance of AnyFlake.
19 20 21 22 23 24 25 26 |
# 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 |
Class Method Details
.parse(flake_id, target_epoch) ⇒ Object
50 51 52 53 54 55 56 57 |
# 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 |
Instance Method Details
#next_id ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# 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) ⇒ Object
46 47 48 |
# File 'lib/anyflake.rb', line 46 def parse(flake_id) AnyFlake.parse(flake_id, @target_epoch) end |