Skip to content

Instantly share code, notes, and snippets.

@ilkersen3
Forked from ryanking/mock_snowflake.rb
Created October 13, 2022 23:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilkersen3/d6f3584175d6cd7bb521668798907516 to your computer and use it in GitHub Desktop.
Save ilkersen3/d6f3584175d6cd7bb521668798907516 to your computer and use it in GitHub Desktop.
module MockSnowflake
TWEPOCH = 1142974214000
WORKERIDBITS = 5
DATACENTERIDBITS = 5
MAXWORKERID = -1 ^ (-1 << WORKERIDBITS)
SEQUENCEBITS = 12
WORKERIDSHIFT = SEQUENCEBITS
DATACENTERIDSHIFT = SEQUENCEBITS + WORKERIDBITS
TIMESTAMPLEFTSHIFT = SEQUENCEBITS + WORKERIDBITS + DATACENTERIDBITS
SEQUENCEMASK = -1 ^ (-1 << SEQUENCEBITS)
WORKER_ID = 0
DATACENTER_ID = 0
def self.get_id(agent)
@sequence ||= 0
t = self.get_timestamp
until !(t < (@last_timestamp || 0))
sleep 0.001
t = self.get_timestamp
end
if @last_timestamp == t
@sequence = (@sequence + 1) & SEQUENCEMASK
if @sequence == 0
t = til_next_millis(@last_timestamp)
end
else
@sequence = 0
end
@last_timestamp = t
((t - TWEPOCH) << TIMESTAMPLEFTSHIFT) |
(DATACENTER_ID << DATACENTERIDSHIFT) |
(WORKER_ID << WORKERIDSHIFT) |
@sequence
end
def self.til_next_millis(last_timestamp)
while last_timestamp == (t = self.get_timestamp)
end
t
end
def self.get_timestamp
((t = Time.now).to_i * 1000) + (t.usec / 1000).to_i
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment