diff --git a/udf-starter-id/pom.xml b/udf-starter-id/pom.xml index 1c858b7..3ace8dd 100644 --- a/udf-starter-id/pom.xml +++ b/udf-starter-id/pom.xml @@ -15,6 +15,12 @@ + + + org.springframework.boot + spring-boot-starter-test + test + org.itkk.udf udf-starter-core diff --git a/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorker.java b/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorker.java index c6ef9e2..c8cfc40 100644 --- a/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorker.java +++ b/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorker.java @@ -35,17 +35,17 @@ public class IdWorker { public static final String MAC_PID_TYPE = "mac_pid"; /** - * 描述 : 机器ID + * 描述 : 机器ID( 0 - 31 ) */ private long workerId; /** - * 描述 : 数据中心ID + * 描述 : 数据中心ID( 0 - 31 ) */ private long datacenterId; /** - * 描述 : 并发控制 + * 描述 : 序列号( 0 - 4095) */ private long sequence = 0L; @@ -95,7 +95,7 @@ public class IdWorker { private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; /** - * 描述 : sequenceMask + * 描述 : 序列号最大值 , 一微秒能产生的ID个数 */ private long sequenceMask = -1L ^ (-1L << sequenceBits); @@ -145,16 +145,14 @@ public class IdWorker { public IdWorker(long workerId, long datacenterId) { // sanity check for workerId if (workerId > maxWorkerId || workerId < 0) { - throw new IllegalArgumentException( - String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { - throw new IllegalArgumentException( - String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; - log.info("datacenterId:{},workerId:{}", maxDatacenterId, maxWorkerId); + log.info("datacenterId:{},workerId:{}", this.datacenterId, this.workerId); } /** @@ -165,9 +163,7 @@ public class IdWorker { public synchronized long nextId() { long timestamp = timeGen(); if (timestamp < lastTimestamp) { - throw new SystemRuntimeException( - String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", - lastTimestamp - timestamp)); + throw new SystemRuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; @@ -178,8 +174,9 @@ public class IdWorker { sequence = 0L; } lastTimestamp = timestamp; - return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) - | (workerId << workerIdShift) | sequence; + log.debug("{} | {} | {} | {}", ((timestamp - twepoch) << timestampLeftShift), (datacenterId << datacenterIdShift), (workerId << workerIdShift), sequence); + log.debug("(({} - {}) << {}) | ({} << {}) | ({} << {}) | {}", timestamp, twepoch, timestampLeftShift, datacenterId, datacenterIdShift, workerId, workerIdShift, sequence); + return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; } /** diff --git a/udf-starter-id/src/main/test/java/org/itkk/udf/id/IdWorkerTest.java b/udf-starter-id/src/main/test/java/org/itkk/udf/id/IdWorkerTest.java new file mode 100644 index 0000000..ffee1a6 --- /dev/null +++ b/udf-starter-id/src/main/test/java/org/itkk/udf/id/IdWorkerTest.java @@ -0,0 +1,48 @@ +package org.itkk.udf.id; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Ignore; +import org.junit.Test; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public class IdWorkerTest { + + @Test + @Ignore + public void id() { + Map map = new HashMap<>(); + int maxCount = 1; + IdWorker idWorker = new IdWorker(10, 20); + for (int i = 0; i < maxCount; i++) { + long id = idWorker.nextId(); + log.info("--------------------------------------------------------------"); + log.info(id + " ---> id长整型"); + log.info(Long.toBinaryString(id) + " ---> id二进制"); + log.info(Long.toBinaryString((-1L ^ (-1L << 12))) + " ---> 序列号最大值,也就是4095"); + log.info(Long.toBinaryString((-1l)) + " ---> 64位,负数的最大值"); + log.info(Long.toBinaryString((-1l << 5l)) + " ---> 按位左移5位"); + log.info(Long.toBinaryString(~(-1l << 5l)) + "---> 取反,获得5位二进制的最大值,也就是31"); + log.info(Long.toBinaryString((id)) + " ---> id ,左移0位,定位到workerId"); + log.info(Long.toBinaryString((id >> 12)) + " ---> id ,左移12位,定位到workerId"); + log.info(Long.toBinaryString((id >> 17)) + " ---> id ,左移17位,定位到datacenterId"); + log.info(Long.toBinaryString((id >> 22)) + " ---> id ,左移22位,定位到timestamp"); + log.info(Long.parseLong(Long.toBinaryString((id) & ~(-1L << 12L)), 2) + " ---> & 运算 , 解析sequence"); + log.info(Long.parseLong(Long.toBinaryString((id >> 12) & ~(-1L << 5L)), 2) + " ---> & 运算 , 解析workerId"); + log.info(Long.parseLong(Long.toBinaryString((id >> 17) & ~(-1L << 5L)), 2) + " ---> & 运算 , 解析datacenterId"); + log.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date(Long.parseLong(Long.toBinaryString((id >> 22) + 1288834974657l), 2))) + " ---> & 运算 , 解析timestamp"); + if (map.containsKey(id)) { + log.warn("重复:" + id); + } + map.put(id, id); + } + //0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 + // 1100100 0101110001 1111010110 0111000000 1 - 00001 - 00001 - 000000000000 ---> 1 ,1 + // 1100100 0101110010 0110110000 1110100110 1 - 00010 - 00010 - 000000000000 ---> 2 ,2 + // 1100100 0101110010 1100010011 1000001000 0 - 11111 - 11111 - 000000000000 ---> 31 , 31 + } +}