web123456

Snowflake Algorithm----ID Generator Tool Class

  • //Snowflake algorithm code implementation
  • public class IdWorker {
  • // The time start marking point is used as a reference. Generally, the nearest time of the system is taken (once it is determined that it cannot change)
  • private final static long twepoch = 1288834974657L;
  • // Number of bits of machine identification
  • private final static long workerIdBits = 5L;
  • // Number of digits of data center identification
  • private final static long datacenterIdBits = 5L;
  • // Maximum value of machine ID
  • private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
  • // Maximum data center ID value
  • private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
  • // Self-increasing position within milliseconds
  • private final static long sequenceBits = 12L;
  • // The machine ID is shifted to the left by 12 bits
  • private final static long workerIdShift = sequenceBits;
  • // The data center ID is shifted left by 17 bits
  • private final static long datacenterIdShift = sequenceBits + workerIdBits;
  • // Milliseconds shift left by 22 bits
  • private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
  • private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
  • /* Last production id timestamp */
  • private static long lastTimestamp = -1L;
  • // 0, concurrent control
  • private long sequence = 0L;
  • private final long workerId;
  • // Data ID part
  • private final long datacenterId;
  • public IdWorker(){
  • this.datacenterId = getDatacenterId(maxDatacenterId);
  • this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
  • }
  • /**
  • * @param workerId
  • * Working machine ID
  • * @param datacenterId
  • * Serial number
  • */
  • public IdWorker(long workerId, long datacenterId) {
  • if (workerId > maxWorkerId || workerId < 0) {
  • throw new IllegalArgumentException(("worker Id can't be greater than %d or less than 0", maxWorkerId));
  • }
  • if (datacenterId > maxDatacenterId || datacenterId < 0) {
  • throw new IllegalArgumentException(("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
  • }
  • this.workerId = workerId;
  • this.datacenterId = datacenterId;
  • }
  • /**
  • * Get the next ID
  • *
  • * @return
  • */
  • public synchronized long nextId() {
  • long timestamp = timeGen();
  • if (timestamp < lastTimestamp) {
  • throw new RuntimeException(("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
  • }
  • if (lastTimestamp == timestamp) {
  • // In the current millisecond, +1
  • sequence = (sequence + 1) & sequenceMask;
  • if (sequence == 0) {
  • // If the current millisecond count is full, wait for the next second
  • timestamp = tilNextMillis(lastTimestamp);
  • }
  • } else {
  • sequence = 0L;
  • }
  • lastTimestamp = timestamp;
  • // ID offset combination generates the final ID and returns the ID
  • long nextId = ((timestamp - twepoch) << timestampLeftShift)
  • | (datacenterId << datacenterIdShift)
  • | (workerId << workerIdShift) | sequence;
  • return nextId;
  • }
  • private long tilNextMillis(final long lastTimestamp) {
  • long timestamp = this.timeGen();
  • while (timestamp <= lastTimestamp) {
  • timestamp = this.timeGen();
  • }
  • return timestamp;
  • }
  • private long timeGen() {
  • return ();
  • }
  • /**
  • * <p>
  • * Get maxWorkerId
  • * </p>
  • */
  • protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
  • StringBuffer mpid = new StringBuffer();
  • (datacenterId);
  • String name = ().getName();
  • if (!()) {
  • /*
  • * GET jvmPid
  • */
  • (("@")[0]);
  • }
  • /*
  • * MAC + PID hashcode gets 16 low digits
  • */
  • return (().hashCode() & 0xffff) % (maxWorkerId + 1);
  • }
  • /**
  • * <p>
  • * Data ID part
  • * </p>
  • */
  • protected static long getDatacenterId(long maxDatacenterId) {
  • long id = 0L;
  • try {
  • InetAddress ip = ();
  • NetworkInterface network = (ip);
  • if (network == null) {
  • id = 1L;
  • } else {
  • byte[] mac = ();
  • id = ((0x000000FF & (long) mac[ - 1])
  • | (0x0000FF00 & (((long) mac[ - 2]) << 8))) >> 6;
  • id = id % (maxDatacenterId + 1);
  • }
  • } catch (Exception e) {
  • (" getDatacenterId: " + ());
  • }
  • return id;
  • }
  • }