Created
January 26, 2012 22:49
-
-
Save ryantenney/1685616 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package us.t4y.scratch; | |
| import org.slf4j.Logger; | |
| import org.slf4j.LoggerFactory; | |
| /** | |
| * Adapted from Twitter's Snowflake | |
| * http://github.com/twitter/snowflake | |
| */ | |
| public class Snowflake { | |
| private static final Logger log = LoggerFactory.getLogger(Snowflake.class); | |
| private static final long epoch = 1288834974657L; | |
| private static final long workerIdBits = 5L; | |
| private static final long datacenterIdBits = 5L; | |
| private static final long sequenceBits = 12L; | |
| private static final long workerIdShift = sequenceBits; | |
| private static final long datacenterIdShift = sequenceBits + workerIdBits; | |
| private static final long timestampShift = sequenceBits + workerIdBits + datacenterIdBits; | |
| private static final long sequenceMask = -1L ^ (-1L << sequenceBits); | |
| private static final long workerIdMask = -1L ^ (-1L << workerIdBits); | |
| private static final long datacenterIdMask = -1L ^ (-1L << datacenterIdBits); | |
| private final long workerId; | |
| private final long datacenterId; | |
| private long sequence = 0L; | |
| private long lastTimestamp = -1L; | |
| public Snowflake(final long datacenterId, final long workerId) { | |
| this.datacenterId = datacenterId & datacenterIdMask; | |
| this.workerId = workerId & workerIdMask; | |
| } | |
| public synchronized long nextId() { | |
| long timestamp = timestamp(); | |
| if (lastTimestamp == timestamp) { | |
| sequence = (sequence + 1) & sequenceMask; | |
| if (sequence == 0) { | |
| System.out.println("rollover"); | |
| timestamp = tilNextMillis(lastTimestamp); | |
| } | |
| } else { | |
| sequence = 0; | |
| } | |
| if (timestamp < lastTimestamp) { | |
| log.error("Clock is moving backwards. Rejecting requests until " + lastTimestamp + "."); | |
| throw new IllegalStateException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds"); | |
| } | |
| lastTimestamp = timestamp; | |
| return ((timestamp - epoch) << timestampShift) | |
| | (datacenterId << datacenterIdShift) | |
| | (workerId << workerIdShift) | |
| | sequence; | |
| } | |
| protected long tilNextMillis(long lastTimestamp) { | |
| long timestamp = timestamp(); | |
| while (timestamp <= lastTimestamp) { | |
| timestamp = timestamp(); | |
| } | |
| return timestamp; | |
| } | |
| protected long timestamp() { | |
| return System.currentTimeMillis(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment