package com.doumee.core.utils; 
 | 
  
 | 
import org.apache.logging.log4j.util.Strings; 
 | 
  
 | 
import java.util.UUID; 
 | 
  
 | 
/** 
 | 
 * A utility to generate id using various strategies. 
 | 
 * 
 | 
 * @author Guang YANG 
 | 
 * @version 1.0 
 | 
 */ 
 | 
public class ID { 
 | 
  
 | 
  private static final SnowflakeIdGenerator snowflake = new SnowflakeIdGenerator(0); 
 | 
  
 | 
  
 | 
  
 | 
  /** 
 | 
   * Generate a random guid string of 32 byte. 
 | 
   */ 
 | 
  public static String nextGUID() { 
 | 
    return UUID.randomUUID().toString().replace("-", Strings.EMPTY).toUpperCase(); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Generate a random uuid string of 36 byte. 
 | 
   */ 
 | 
  public static String nextUUID() { 
 | 
    return UUID.randomUUID().toString(); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Generate a long number of 20 bit which is monotonically increasing by each call. 
 | 
   */ 
 | 
  public static long nextSnowflakeId() { 
 | 
    return snowflake.nextId(); 
 | 
  } 
 | 
  
 | 
  public static class SnowflakeIdGenerator { 
 | 
  
 | 
    private final long workerIdBits = 10L; 
 | 
    private final long maxWorkerId = -1L ^ (-1L << workerIdBits); 
 | 
    private final long sequenceBits = 12L; 
 | 
    private final long workerIdShift = sequenceBits; 
 | 
    private final long timestampLeftShift = sequenceBits + workerIdBits; 
 | 
    private final long sequenceMask = -1L ^ (-1L << sequenceBits); 
 | 
  
 | 
    private long workerId; 
 | 
    private long sequence = 0L; 
 | 
    private long lastTimestamp = -1L; 
 | 
  
 | 
    public SnowflakeIdGenerator(long workerId) { 
 | 
      if (workerId > maxWorkerId || workerId < 0) { 
 | 
        throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); 
 | 
      } 
 | 
      this.workerId = workerId; 
 | 
    } 
 | 
  
 | 
    public synchronized long nextId() { 
 | 
      long timestamp = System.currentTimeMillis(); 
 | 
      if (timestamp < lastTimestamp) { 
 | 
        throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); 
 | 
      } 
 | 
      if (lastTimestamp == timestamp) { 
 | 
        sequence = (sequence + 1) & sequenceMask; 
 | 
        if (sequence == 0) { 
 | 
          timestamp = tilNextMillis(lastTimestamp); 
 | 
        } 
 | 
      } else { 
 | 
        sequence = 0L; 
 | 
      } 
 | 
  
 | 
      lastTimestamp = timestamp; 
 | 
  
 | 
      return (timestamp << timestampLeftShift) | (workerId << workerIdShift) | sequence; 
 | 
    } 
 | 
  
 | 
    protected long tilNextMillis(long lastTimestamp) { 
 | 
      long timestamp = System.currentTimeMillis(); 
 | 
      while (timestamp <= lastTimestamp) { 
 | 
        timestamp = System.currentTimeMillis(); 
 | 
      } 
 | 
      return timestamp; 
 | 
    } 
 | 
  
 | 
  } 
 | 
  
 | 
} 
 |