Class: DiscordRDA::Snowflake

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/discord_rda/core/snowflake.rb

Overview

Discord Snowflake ID value object. Provides extraction of timestamp, worker ID, process ID, and increment.

Discord snowflakes are 64-bit integers with the following structure:

  • 41 bits: timestamp (milliseconds since Discord epoch)

  • 5 bits: worker ID

  • 5 bits: process ID

  • 12 bits: increment

Examples:

Creating a snowflake

snowflake = Snowflake.new("1234567890123456789")
snowflake.timestamp # => 2021-01-01 00:00:00 UTC
snowflake.time # => Same as timestamp

Constant Summary collapse

DISCORD_EPOCH =

Discord epoch (January 1, 2015)

1_420_070_400_000
WORKER_ID_BITS =

Bit masks for snowflake components

0x3E0000
PROCESS_ID_BITS =
0x1F000
INCREMENT_BITS =
0xFFF

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Snowflake

Create a new snowflake

Parameters:

  • value (String, Integer)

    The snowflake value



50
51
52
53
# File 'lib/discord_rda/core/snowflake.rb', line 50

def initialize(value)
  @value = value.to_i
  freeze
end

Instance Attribute Details

#valueInteger (readonly)

Returns The raw snowflake value.

Returns:

  • (Integer)

    The raw snowflake value



28
29
30
# File 'lib/discord_rda/core/snowflake.rb', line 28

def value
  @value
end

Class Method Details

.generate(time = Time.now.utc) ⇒ Snowflake

Generate a new snowflake (for testing only - Discord generates real snowflakes)

Parameters:

  • time (Time) (defaults to: Time.now.utc)

    The time for the snowflake

Returns:



34
35
36
37
38
# File 'lib/discord_rda/core/snowflake.rb', line 34

def generate(time = Time.now.utc)
  timestamp = ((time.to_f * 1000).to_i - DISCORD_EPOCH) << 22
  increment = rand(0..INCREMENT_BITS)
  new(timestamp | increment)
end

.parse(value) ⇒ Snowflake

Parse a snowflake from string or integer

Parameters:

  • value (String, Integer)

    The snowflake value

Returns:



43
44
45
# File 'lib/discord_rda/core/snowflake.rb', line 43

def parse(value)
  new(value)
end

Instance Method Details

#<=>(other) ⇒ Integer

Compare snowflakes by timestamp

Parameters:

  • other (Snowflake)

    Other snowflake to compare

Returns:

  • (Integer)

    Comparison result



83
84
85
# File 'lib/discord_rda/core/snowflake.rb', line 83

def <=>(other)
  timestamp <=> other.timestamp
end

#==(other) ⇒ Boolean Also known as: eql?

Check equality with another snowflake or value

Parameters:

  • other (Object)

    Object to compare

Returns:

  • (Boolean)

    True if equal



92
93
94
# File 'lib/discord_rda/core/snowflake.rb', line 92

def ==(other)
  other.is_a?(Snowflake) && @value == other.value
end

#hashInteger

Get the hash code

Returns:

  • (Integer)

    Hash code



99
100
101
# File 'lib/discord_rda/core/snowflake.rb', line 99

def hash
  @value.hash
end

#incrementInteger

Get the increment from the snowflake

Returns:

  • (Integer)

    The increment



76
77
78
# File 'lib/discord_rda/core/snowflake.rb', line 76

def increment
  @value & INCREMENT_BITS
end

#inspectString

Inspect the snowflake

Returns:

  • (String)

    Inspect string



117
118
119
# File 'lib/discord_rda/core/snowflake.rb', line 117

def inspect
  "#<Snowflake value=#{@value} time=#{timestamp.iso8601}>"
end

#process_idInteger

Get the process ID from the snowflake

Returns:

  • (Integer)

    The process ID



70
71
72
# File 'lib/discord_rda/core/snowflake.rb', line 70

def process_id
  (@value & PROCESS_ID_BITS) >> 12
end

#timestampTime Also known as: time

Get the timestamp from the snowflake

Returns:

  • (Time)

    The timestamp (UTC)



57
58
59
# File 'lib/discord_rda/core/snowflake.rb', line 57

def timestamp
  Time.at(((@value >> 22) + DISCORD_EPOCH) / 1000.0).utc
end

#to_iInteger

Convert to integer

Returns:

  • (Integer)

    The raw value



105
106
107
# File 'lib/discord_rda/core/snowflake.rb', line 105

def to_i
  @value
end

#to_sString

Convert to string

Returns:

  • (String)

    String representation



111
112
113
# File 'lib/discord_rda/core/snowflake.rb', line 111

def to_s
  @value.to_s
end

#worker_idInteger

Get the worker ID from the snowflake

Returns:

  • (Integer)

    The worker ID



64
65
66
# File 'lib/discord_rda/core/snowflake.rb', line 64

def worker_id
  (@value & WORKER_ID_BITS) >> 17
end