Created
December 29, 2017 03:12
-
-
Save xuanyu-h/79a5dd28e13d9d27df949d581f65d89f to your computer and use it in GitHub Desktop.
Twitter 雪花算法
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
/** | |
* @author Spirit | |
* @date 2017/12/14 | |
*/ | |
/** | |
* Twitter 雪花算法 | |
* | |
* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 | |
* 1 位标识 | |
* 41 位时间戳 | |
* 10 位数据及机器中心位 | |
* 12 位序列位 | |
*/ | |
public class SnowFlakeUtil { | |
/** 起始时间戳: 2017-01-01 */ | |
private final long startTimeStamp = 1483200000000L; | |
public static final int NODE_SHIFT = 10; | |
public static final int SEQ_SHIFT = 12; | |
public static final short MAX_NODE = 1024; | |
public static final short MAX_SEQUENCE = 4096; | |
private short sequence; | |
private long referenceTime; | |
private int node; | |
public SnowFlakeUtil(int node) { | |
if (node < 0 || node > MAX_NODE) { | |
throw new IllegalArgumentException(String.format("node must be between %s and %s", 0, MAX_NODE)); | |
} | |
this.node = node; | |
} | |
public long next() { | |
long currentTime = System.currentTimeMillis(); | |
long counter; | |
synchronized(this) { | |
if (currentTime < referenceTime) { | |
throw new RuntimeException(String.format("Last referenceTime %s is after reference time %s", referenceTime, currentTime)); | |
} else if (currentTime > referenceTime) { | |
this.sequence = 0; | |
} else { | |
if (this.sequence < SnowFlakeUtil.MAX_SEQUENCE) { | |
this.sequence++; | |
} else { | |
throw new RuntimeException("Sequence exhausted at " + this.sequence); | |
} | |
} | |
counter = this.sequence; | |
referenceTime = currentTime; | |
} | |
return (currentTime - startTimeStamp) << NODE_SHIFT << SEQ_SHIFT | node << SEQ_SHIFT | counter; | |
} | |
public static long getLongId(int node) { | |
SnowFlakeUtil s = new SnowFlakeUtil(node); | |
return s.next(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment