Class: AnyFlake

Inherits:
Object
  • Object
show all
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

Constructor Details

#initialize(target_epoch, node_id, sequence = 0) ⇒ AnyFlake

Returns a new instance of AnyFlake.

Raises:



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_idObject



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