添加snowflake的反向解析验证代码

This commit is contained in:
王康
2017-09-03 00:16:13 +08:00
parent c9ae8e5482
commit 324dc2326c
3 changed files with 65 additions and 14 deletions
+6
View File
@@ -15,6 +15,12 @@
</parent>
<!-- 依赖 -->
<dependencies>
<!-- spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.itkk.udf</groupId>
<artifactId>udf-starter-core</artifactId>
@@ -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;
}
/**
@@ -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<Long, Long> 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
}
}