Skip to content

Instantly share code, notes, and snippets.

@xuanyu-h
Created December 29, 2017 03:12
Show Gist options
  • Save xuanyu-h/79a5dd28e13d9d27df949d581f65d89f to your computer and use it in GitHub Desktop.
Save xuanyu-h/79a5dd28e13d9d27df949d581f65d89f to your computer and use it in GitHub Desktop.
Twitter 雪花算法
/**
* @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