twitter_snowflake 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b6823234421cda30700685779281840c03182376a020a90d15cac4f3a110bf10
4
+ data.tar.gz: e68055bf4fa8c33b23e2816bf15b80c8dc5ffa9e39642ffcd2b8baea0674762c
5
+ SHA512:
6
+ metadata.gz: c43dc596687839df000374a8137fcd5cf4c9f0e9ef9480589aaed853fb83ffb82697113ca312ca3aa2b4511d4c8735b3a94a932ed66d54c0c8f263677f12e01c
7
+ data.tar.gz: 300004e8f1a00eeb413961c596fe23c1b40d6058f3283d3bfeb0f967b77cf1eff85ddb8b4479147ce6126cb1f0d8152bd651d06762ec3defa469904eeb23921c
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /profiles/
10
+ /tmp/
11
+ /.idea/
12
+ .DS_Store
13
+ *.gem
14
+ **.sw*
15
+
16
+ /vendor/bundle
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # TwitterSnowflake.rb
2
+
3
+ A Ruby library to handle Twitter snowflake IDs.
4
+
5
+ ## âŦ‡ī¸ Installation
6
+
7
+ There are two ways to install this library:
8
+
9
+ **1. Bundler**
10
+
11
+ Run `bundle init` to generate a Gemfile, append the following line to it and run `bundle install`.
12
+
13
+ ```
14
+ gem 'twitter_snowflake', '~> 0.0.1'
15
+ ```
16
+
17
+ **2. Gem**
18
+
19
+ Or you can use Ruby's package manager: gem. Open your terminal and run the following command:
20
+
21
+ ```
22
+ gem install twitter_snowflake
23
+ ```
24
+
25
+ ## đŸ“Ļ Dependencies
26
+
27
+ ### Runtime
28
+
29
+ TwitterSnowflake.rb does not rely on any third-party library.
30
+
31
+ ### Development
32
+
33
+ - [YARD](https://rubygems.org/gems/yard/versions/0.9.20) – to generate documentation.
34
+ - [Rubocop](https://rubygems.org/gems/rubocop/versions/0.76.0) – to spot bad code smells.
35
+
36
+ ## 📚 Documentation
37
+
38
+ You can find the documentation in [Rubydoc](https://www.rubydoc.info/github/asyncnoodle/TwitterSnowflake.rb).
39
+
40
+ ## đŸ•šī¸ Usage
41
+
42
+ To parse a snowflake ID, use `TwitterSnowflake.parse`:
43
+
44
+ ```ruby
45
+ require 'twitter_snowflake'
46
+
47
+ snowflake = TwitterSnowflake.parse 948_350_713_171_619_840
48
+ # => #<TwitterSnowflake::Snowflake:0x00005584b970d878
49
+ # @epoch=1288834974657,
50
+ # @id=948350713171619840,
51
+ # @increment=0,
52
+ # @process_id=19,
53
+ # @time=2018-01-02 22:30:04 -0200,
54
+ # @timestamp=1514939404181,
55
+ # @worker_id=0>
56
+ ```
57
+
58
+ If you don't need a whole `Snowflake` instance, you can use `TwitterSnowflake`'s utility class methods:
59
+
60
+ ```ruby
61
+ TwitterSnowflake.timestamp 948_350_713_171_619_840 # => 1514939404181
62
+ ```
63
+
64
+ Calculations are made with Twitter's epoch by default (`1_288_834_974_657`). You can change the epoch value by passing a keyword argument to `TwitterSnowflake.parse` or `TwitterSnowflake.timestamp`:
65
+
66
+ ```ruby
67
+ discord_epoch = 1_420_070_400_000
68
+ id = 649_027_890_029_133_824
69
+
70
+ TwitterSnowflake.timestamp id, epoch: discord_epoch # => 1574810707338
71
+
72
+ TwitterSnowflake.parse id, epoch: discord_epoch
73
+ # => <TwitterSnowflake::Snowflake:0x000056544c9e9818
74
+ # @epoch=1420070400000,
75
+ # @id=649027890029133824,
76
+ # @increment=0,
77
+ # @process_id=0,
78
+ # @time=2019-11-26 20:25:07 -0300,
79
+ # @timestamp=1574810707338,
80
+ # @worker_id=1>
81
+ ```
82
+
83
+ It is also possible to generate a snowflake yourself with `TwitterSnowflake.synthesize`:
84
+
85
+ ```ruby
86
+ snowflake = TwitterSnowflake.synthesize(
87
+ epoch: 1_420_070_400_000, # defaults to Twitter's epoch if no value is provided
88
+ timestamp: 1_574_810_707_338,
89
+ worker_id: 1,
90
+ process_id: 0,
91
+ increment: 0,
92
+ )
93
+
94
+ p snowflake.id # => 649027890029133824
95
+ ```
96
+
97
+ ## 📄 License
98
+
99
+ TwitterSnowflake.rb is licensed under [MIT](LICENSE).
100
+
101
+ ## âœī¸ Contributors
102
+
103
+ - [asyncnoodle](https://github.com/asyncnoodle) – author & maintainer.
104
+
105
+ I'm looking to improve TwitterSnowflake.rb, so feel free to contribute!
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'twitter_snowflake/version'
4
+ require 'twitter_snowflake/snowflake'
5
+
6
+ # TwitterSnowflake is a library to parse snowflake IDs.
7
+ module TwitterSnowflake
8
+ # Twitter's epoch in milliseconds. Used as default epoch to parse IDs.
9
+ TWITTER_EPOCH = 1_288_834_974_657
10
+
11
+ # Timestamp offset (low-order bit of the timestamp collection)
12
+ TIMESTAMP_BINARY_OFFSET = 22
13
+
14
+ # Worker ID offset (low-order bit of the worker ID collection)
15
+ WORKER_ID_BINARY_OFFSET = 17
16
+
17
+ # Mask to extract worker ID.
18
+ WORKER_ID_MASK = 0x3E000
19
+
20
+ # Process ID offset (low-order bit of the process ID collection)
21
+ PROCESS_ID_BINARY_OFFSET = 12
22
+
23
+ # Mask to extract process ID.
24
+ PROCESS_ID_MASK = 0x1F000
25
+
26
+ # Mask to extract increment.
27
+ INCREMENT_MASK = 0xFFF
28
+
29
+ class << self
30
+ # Creates a snowflake object for any given timestamp, worker ID, process ID and increment.
31
+ #
32
+ # @param epoch [Integer] base epoch in milliseconds to perform calculations.
33
+ # @param timestamp [Integer] the timestamp in milliseconds.
34
+ #
35
+ # @return [Snowflake] the generated snowflake.
36
+ def synthesize(timestamp:, worker_id: 0, process_id: 0, increment: 0, epoch: TWITTER_EPOCH)
37
+ id = (timestamp - epoch) << TIMESTAMP_BINARY_OFFSET
38
+ id += (worker_id << WORKER_ID_BINARY_OFFSET)
39
+ id += (process_id << PROCESS_ID_BINARY_OFFSET)
40
+ id += increment
41
+
42
+ Snowflake.new(id: id, epoch: epoch)
43
+ end
44
+
45
+ # Parses a snowflake ID.
46
+ #
47
+ # @param id [Integer] the snowflake ID.
48
+ # @param epoch [Integer] base epoch in milliseconds to perform calculations.
49
+ #
50
+ # @return [Snowflake] a snowflake object.
51
+ def parse(id, epoch: TWITTER_EPOCH)
52
+ Snowflake.new(id: id, epoch: epoch)
53
+ end
54
+
55
+ # Extracts the timestamp from a snowflake ID.
56
+ #
57
+ # @param id [Integer] the snowflake ID.
58
+ # @param epoch [Integer] base epoch in milliseconds to perform calculations.
59
+ #
60
+ # @return [Integer] the timestamp in milliseconds.
61
+ def timestamp(id, epoch: TWITTER_EPOCH)
62
+ (id >> TIMESTAMP_BINARY_OFFSET) + epoch
63
+ end
64
+
65
+ # Extracts the worker ID from a snowflake ID.
66
+ #
67
+ # @param id [Integer] the snowflake ID.
68
+ #
69
+ # @return [Integer] the worker ID.
70
+ def worker_id(id)
71
+ (id & WORKER_ID_MASK) >> WORKER_ID_BINARY_OFFSET
72
+ end
73
+
74
+ # Extracts the process ID from a snowflake ID.
75
+ #
76
+ # @param id [Integer] the snowflake ID.
77
+ #
78
+ # @return [Integer] the process ID.
79
+ def process_id(id)
80
+ (id & PROCESS_ID_MASK) >> PROCESS_ID_BINARY_OFFSET
81
+ end
82
+
83
+ # Extracts the increment from a snowflake ID.
84
+ #
85
+ # @param id [Integer] the snowflake ID.
86
+ #
87
+ # @return [Integer] the increment.
88
+ def increment(id)
89
+ id & INCREMENT_MASK
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TwitterSnowflake
4
+ # A snowflake ID as a Ruby object.
5
+ class Snowflake
6
+ # @return [Integer] the snowflake ID in its original form.
7
+ attr_reader :id
8
+
9
+ # @return [Integer] the base epoch in milliseconds to perform calculations.
10
+ attr_reader :epoch
11
+
12
+ # @return [Integer] the timestamp extracted from the ID in milliseconds.
13
+ attr_reader :timestamp
14
+
15
+ # @return [Integer] the worker ID extracted form the ID.
16
+ attr_reader :worker_id
17
+
18
+ # @return [Integer] the proccess ID extracted from the ID.
19
+ attr_reader :process_id
20
+
21
+ # @return [Integer] the increment extracted from the ID.
22
+ attr_reader :increment
23
+
24
+ # @return [Time] the timestamp as a Time object
25
+ attr_reader :time
26
+
27
+ # @param id [Integer] the ID itself.
28
+ # @param epoch [Intger] base epoch in milliseconds to perform calculations.
29
+ def initialize(id:, epoch:)
30
+ # Data used during extraction process
31
+ @id = id
32
+ @epoch = epoch
33
+
34
+ # Extracting data
35
+ @timestamp = TwitterSnowflake.timestamp(@id, epoch: @epoch)
36
+ @worker_id = TwitterSnowflake.worker_id(@id)
37
+ @process_id = TwitterSnowflake.process_id(@id)
38
+ @increment = TwitterSnowflake.increment(@id)
39
+
40
+ # Useful information
41
+ @time = Time.at(@timestamp / 1000.0)
42
+ end
43
+
44
+ # Checks if two snowflakes are equal. Two snowflakes are considered equal
45
+ # if both have the same ID and are based on the same epoch.
46
+ #
47
+ # @param other [Snowflake] the other snowflake.
48
+ #
49
+ # @return [Boolean] whether the snowflakes are equal or not.
50
+ def ==(other)
51
+ (@id == other.id) && (@epoch == other.epoch)
52
+ end
53
+
54
+ # Checks if this snowflake has been generated before another snowflake.
55
+ #
56
+ # @param other [Snowflake] the other snowflake.
57
+ #
58
+ # @return [Boolean] whether this snowflake has been generated before another snowflake or not.
59
+ def before?(other)
60
+ @timestamp < other.timestamp
61
+ end
62
+
63
+ # Checks if this snowflake has been generated after another snowflake.
64
+ #
65
+ # @param other [Snowflake] the other snowflake.
66
+ #
67
+ # @return [Boolean] whether this snowflake has been generated after another snowflake or not.
68
+ def after?(other)
69
+ @timestamp > other.timestamp
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TwitterSnowflake
4
+ VERSION = '0.0.2'
5
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'twitter_snowflake/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'twitter_snowflake'
9
+ spec.version = TwitterSnowflake::VERSION
10
+ spec.authors = %w[asyncnoodle]
11
+
12
+ spec.summary = 'Ruby library to handle Twitter snowflake IDs.'
13
+ spec.homepage = 'https://github.com/asyncnoodle/TwitterSnowflake.rb'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|examples|lib/discordrb/webhooks)/}) }
17
+ spec.require_paths = %w[lib]
18
+
19
+ spec.add_development_dependency 'rspec', '~> 3.8.0'
20
+ spec.add_development_dependency 'rubocop', '~> 0.74.0'
21
+ spec.add_development_dependency 'yard', '~> 0.9.9'
22
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: twitter_snowflake
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - asyncnoodle
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.8.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.8.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.74.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.74.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.9.9
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.9
55
+ description:
56
+ email:
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".gitignore"
62
+ - Gemfile
63
+ - README.md
64
+ - lib/twitter_snowflake.rb
65
+ - lib/twitter_snowflake/snowflake.rb
66
+ - lib/twitter_snowflake/version.rb
67
+ - twitter_snowflake.gemspec
68
+ homepage: https://github.com/asyncnoodle/TwitterSnowflake.rb
69
+ licenses:
70
+ - MIT
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubygems_version: 3.0.3
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Ruby library to handle Twitter snowflake IDs.
91
+ test_files: []