mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
【开源之夏】新增UUIDv7的生成器
This commit is contained in:
parent
f0c591a1b1
commit
876a69e8c2
@ -185,18 +185,20 @@ public class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取随机生成的UUIDv7
|
||||
* 获取随机生成的UUIDv7<br>
|
||||
* 【开源之夏】贡献内容,见:https://gitee.com/dromara/hutool/pulls/1263
|
||||
*
|
||||
* @return UUIDv7
|
||||
* @author Cason(https://gitee.com/Casonhqc)
|
||||
*/
|
||||
public static UUID randomUUID7() {
|
||||
byte[] randomBytes = new byte[16];
|
||||
final byte[] randomBytes = new byte[16];
|
||||
final Random ng = Holder.NUMBER_GENERATOR;
|
||||
ng.nextBytes(randomBytes);
|
||||
|
||||
long[] v7Time = getV7Time();
|
||||
long milli = v7Time[0];
|
||||
long seq = v7Time[1];
|
||||
final long[] v7Time = getV7Time();
|
||||
final long milli = v7Time[0];
|
||||
final long seq = v7Time[1];
|
||||
|
||||
randomBytes[0] = (byte) (milli >> 40);
|
||||
randomBytes[1] = (byte) (milli >> 32);
|
||||
@ -208,20 +210,20 @@ public class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||
randomBytes[6] = (byte) ((0x70) | (0x0F & (seq >> 8)));
|
||||
randomBytes[7] = (byte) seq;
|
||||
randomBytes[8] &= 0x3f; /* clear variant */
|
||||
randomBytes[8] |= 0x80; /* set to IETF variant */
|
||||
randomBytes[8] |= (byte) 0x80; /* set to IETF variant */
|
||||
|
||||
return new UUID(ByteUtil.toLong(randomBytes, 0, ByteOrder.BIG_ENDIAN),
|
||||
ByteUtil.toLong(randomBytes, 8, ByteOrder.BIG_ENDIAN));
|
||||
}
|
||||
|
||||
private static long[] getV7Time() {
|
||||
long nano = System.nanoTime();
|
||||
final long nano = System.nanoTime();
|
||||
long milli = nano / NANOS_PER_MILLI;
|
||||
long seq = (nano - milli * NANOS_PER_MILLI) >> 8;
|
||||
long now = (milli << 12) + seq;
|
||||
|
||||
while (true) {
|
||||
long last = lastV7time.get();
|
||||
final long last = lastV7time.get();
|
||||
if (now <= last) {
|
||||
now = last + 1;
|
||||
milli = now >> 12;
|
||||
|
@ -31,7 +31,6 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
@ -79,7 +78,7 @@ public class IdUtilTest {
|
||||
timer.start();
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
UUID.randomUUID().toString().replace("-", "");
|
||||
java.util.UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
timer.stop();
|
||||
Console.log(timer.getLastTaskTimeMillis());
|
||||
@ -169,8 +168,8 @@ public class IdUtilTest {
|
||||
|
||||
@Test
|
||||
public void testUUIDv7Format() {
|
||||
org.dromara.hutool.core.data.id.UUID uuid = org.dromara.hutool.core.data.id.UUID.randomUUID7();
|
||||
String uuidStr = uuid.toString();
|
||||
final org.dromara.hutool.core.data.id.UUID uuid = org.dromara.hutool.core.data.id.UUID.randomUUID7();
|
||||
final String uuidStr = uuid.toString();
|
||||
|
||||
// 验证UUID字符串格式是否符合标准
|
||||
assertTrue(uuidStr.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"));
|
||||
@ -178,7 +177,7 @@ public class IdUtilTest {
|
||||
|
||||
@Test
|
||||
public void testUUIDv7Properties() {
|
||||
org.dromara.hutool.core.data.id.UUID uuid = org.dromara.hutool.core.data.id.UUID.randomUUID7();
|
||||
final org.dromara.hutool.core.data.id.UUID uuid = org.dromara.hutool.core.data.id.UUID.randomUUID7();
|
||||
|
||||
// 验证版本号是否为7
|
||||
assertEquals(7, uuid.version());
|
||||
@ -190,11 +189,11 @@ public class IdUtilTest {
|
||||
|
||||
@RepeatedTest(10)
|
||||
public void testUUIDv7Uniqueness() {
|
||||
Set<org.dromara.hutool.core.data.id.UUID> uuids = new HashSet<>();
|
||||
final Set<org.dromara.hutool.core.data.id.UUID> uuids = new HashSet<>();
|
||||
|
||||
// 生成100万个UUIDv7,验证是否有重复
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
org.dromara.hutool.core.data.id.UUID uuid = org.dromara.hutool.core.data.id.UUID.randomUUID7();
|
||||
final org.dromara.hutool.core.data.id.UUID uuid = org.dromara.hutool.core.data.id.UUID.randomUUID7();
|
||||
assertFalse(uuids.contains(uuid));
|
||||
uuids.add(uuid);
|
||||
}
|
||||
@ -207,7 +206,7 @@ public class IdUtilTest {
|
||||
|
||||
// 验证连续生成的1000个UUIDv7是否呈单调递增趋势
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
org.dromara.hutool.core.data.id.UUID next = org.dromara.hutool.core.data.id.UUID.randomUUID7();
|
||||
final org.dromara.hutool.core.data.id.UUID next = org.dromara.hutool.core.data.id.UUID.randomUUID7();
|
||||
assertTrue(next.compareTo(prev) > 0);
|
||||
prev = next;
|
||||
}
|
||||
@ -217,6 +216,7 @@ public class IdUtilTest {
|
||||
* UUIDv7的性能测试
|
||||
*/
|
||||
@Test
|
||||
@Disabled
|
||||
public void testUUIDv7Benchmark() {
|
||||
final StopWatch timer = DateUtil.createStopWatch();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user