Skip to content

Instantly share code, notes, and snippets.

@geotheory
Created November 27, 2020 09:09
Show Gist options
  • Save geotheory/1faa608ef666a34db811949e344618a2 to your computer and use it in GitHub Desktop.
Save geotheory/1faa608ef666a34db811949e344618a2 to your computer and use it in GitHub Desktop.
library(bit64)
require(tidyverse)
twepoch <- as.integer64('1288834974657')
base <- as.integer64(2)
datacenter_id_bits <- 5
worker_id_bits <- 5
sequence_id_bits <- 12
max_datacenter_id <- 1 * base^datacenter_id_bits
max_worker_id <- 1 * base^worker_id_bits
max_sequence_id <- 1 * base^sequence_id_bits
max_timestamp <- base^(64 - datacenter_id_bits - worker_id_bits - sequence_id_bits)
# generate a twitter-snowflake id, based on
# https://github.com/twitter/snowflake/blob/master/src/main/scala/com/twitter/service/snowflake/IdWorker.scala
make_snowflake <- function(timestamp_ms, datacenter_id, worker_id, sequence_id, twepoch = as.integer64('1288834974657')) {
stopifnot(is.character(timestamp_ms) || is.integer64(timestamp_ms))
timestamp_ms <- as.integer64(timestamp_ms)
sid <- ((timestamp_ms - twepoch) %% max_timestamp) * base^datacenter_id_bits * base^worker_id_bits * base^sequence_id_bits
sid <- sid + (datacenter_id %% max_datacenter_id) * base^worker_id_bits * base^sequence_id_bits
sid <- sid + (worker_id %% max_worker_id) * base^sequence_id_bits
sid <- sid + sequence_id %% max_sequence_id
sid
}
# inversely transform a snowflake id back to its components.
melt_snowflake <- function(snowflake_id, twepoch = as.integer64('1288834974657')) {
stopifnot(is.character(snowflake_id) || is.integer64(snowflake_id))
snowflake_id <- as.integer64(snowflake_id)
sequence_id <- snowflake_id %% max_sequence_id
worker_id <- (snowflake_id %/% base^sequence_id_bits) %% max_worker_id
datacenter_id <- (snowflake_id %/% base^sequence_id_bits %/% base^worker_id_bits) %% max_datacenter_id
timestamp_ms <- snowflake_id %/% base^sequence_id_bits %/% base^worker_id_bits %/% base^datacenter_id_bits
timestamp_ms <- timestamp_ms + twepoch
list(timestamp_ms = timestamp_ms,
datacenter_id = datacenter_id,
worker_id = worker_id,
sequence_id = sequence_id)
}
x = melt_snowflake('1312686530822103042') # 4:08 AM · Sep 20, 2017
xt = x$timestamp_ms
as.POSIXct(as.numeric(xt)/1000, origin='1970-01-01')
make_snowflake(x$timestamp_ms, x$datacenter_id, x$worker_id, x$sequence_id)
combs = expand.grid(ts = xt+(-5:5), datacenter_id = 1:10, worker_id = 1:20, sequence_id = 1:5) %>% as_tibble() %>%
rowwise() %>% mutate(status_id = make_snowflake(ts, datacenter_id, worker_id, sequence_id)) %>%
ungroup() %>% mutate(status_id = as.character(status_id))
combs %>% mutate(tseg = substr(status_id,1,12)) %>% count(ts, tseg)
last_status = '1312686530821885953'
last_status_ts = as.integer64(substr(last_status,1,12))
status_first = paste0(substr(last_status,1,12), '0000000')
status_last = paste0(as.character(last_status_ts + 1), '0000000')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment