mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
Snowflake增加方法:根据传入时间戳,计算ID起终点
This commit is contained in:
parent
47c07d94ad
commit
3ef6b7ed8f
@ -14,8 +14,9 @@ package org.dromara.hutool.core.data.id;
|
||||
|
||||
import org.dromara.hutool.core.date.SystemClock;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.util.RandomUtil;
|
||||
import org.dromara.hutool.core.lang.tuple.Pair;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.RandomUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
@ -259,6 +260,40 @@ public class Snowflake implements Serializable {
|
||||
return Long.toString(nextId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据传入时间戳-计算ID起终点
|
||||
*
|
||||
* @param timestampStart 开始时间戳
|
||||
* @param timestampEnd 结束时间戳
|
||||
* @return key-ID起点,Value-ID终点
|
||||
* @since 5.8.23
|
||||
*/
|
||||
public Pair<Long, Long> getIdScopeByTimestamp(final long timestampStart, final long timestampEnd) {
|
||||
return getIdScopeByTimestamp(timestampStart, timestampEnd, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据传入时间戳-计算ID起终点 Gitee/issues/I60M14
|
||||
*
|
||||
* @param timestampStart 开始时间戳
|
||||
* @param timestampEnd 结束时间戳
|
||||
* @param ignoreCenterAndWorker 是否忽略数据中心和机器节点的占位,忽略后可获得分布式环境全局可信赖的起终点。
|
||||
* @return key-ID起点,Value-ID终点
|
||||
* @since 5.8.23
|
||||
*/
|
||||
public Pair<Long, Long> getIdScopeByTimestamp(final long timestampStart, final long timestampEnd, final boolean ignoreCenterAndWorker) {
|
||||
final long startTimeMinId = (timestampStart - twepoch) << TIMESTAMP_LEFT_SHIFT;
|
||||
final long endTimeMinId = (timestampEnd - twepoch) << TIMESTAMP_LEFT_SHIFT;
|
||||
if (ignoreCenterAndWorker) {
|
||||
final long endId = endTimeMinId | ~(-1 << TIMESTAMP_LEFT_SHIFT);
|
||||
return Pair.of(startTimeMinId, endId);
|
||||
} else {
|
||||
final long startId = startTimeMinId | (dataCenterId << DATA_CENTER_ID_SHIFT) | (workerId << WORKER_ID_SHIFT);
|
||||
final long endId = endTimeMinId | (dataCenterId << DATA_CENTER_ID_SHIFT) | (workerId << WORKER_ID_SHIFT) | SEQUENCE_MASK;
|
||||
return Pair.of(startId, endId);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------ Private method start
|
||||
|
||||
/**
|
||||
|
@ -128,6 +128,7 @@ public class PathCopier extends SrcToDestCopier<Path, PathCopier> {
|
||||
return copyFile(src, target, options);
|
||||
}
|
||||
|
||||
// region private methods
|
||||
/**
|
||||
* 拷贝目录下的所有文件或目录到目标目录中,此方法不支持文件对文件的拷贝。
|
||||
* <ul>
|
||||
@ -161,8 +162,8 @@ public class PathCopier extends SrcToDestCopier<Path, PathCopier> {
|
||||
* @throws IORuntimeException IO异常
|
||||
*/
|
||||
private static Path copyFile(final Path src, final Path target, final CopyOption... options) throws IORuntimeException {
|
||||
Assert.notNull(src, "Source File is null !");
|
||||
Assert.notNull(target, "Destination File or directory is null !");
|
||||
Assert.notNull(src, "Source file is null !");
|
||||
Assert.notNull(target, "Target file or directory is null !");
|
||||
|
||||
final Path targetPath = PathUtil.isDirectory(target) ? target.resolve(src.getFileName()) : target;
|
||||
// 创建级联父目录
|
||||
@ -173,4 +174,5 @@ public class PathCopier extends SrcToDestCopier<Path, PathCopier> {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
@ -13,11 +13,13 @@
|
||||
package org.dromara.hutool.core.lang;
|
||||
|
||||
import org.dromara.hutool.core.collection.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.exception.HutoolException;
|
||||
import org.dromara.hutool.core.data.id.IdUtil;
|
||||
import org.dromara.hutool.core.data.id.Snowflake;
|
||||
import org.dromara.hutool.core.exception.HutoolException;
|
||||
import org.dromara.hutool.core.lang.tuple.Pair;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.thread.ThreadUtil;
|
||||
import org.dromara.hutool.core.util.RandomUtil;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -116,4 +118,27 @@ public class SnowflakeTest {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试-根据传入时间戳-计算ID起终点
|
||||
*/
|
||||
@Test
|
||||
public void snowflakeTestGetIdScope() {
|
||||
final long workerId = RandomUtil.randomLong(31);
|
||||
final long dataCenterId = RandomUtil.randomLong(31);
|
||||
final Snowflake idWorker = new Snowflake(workerId, dataCenterId);
|
||||
final long generatedId = idWorker.nextId();
|
||||
// 随机忽略数据中心和工作机器的占位
|
||||
final boolean ignore = RandomUtil.randomBoolean();
|
||||
final long createTimestamp = idWorker.getGenerateDateTime(generatedId);
|
||||
final Pair<Long, Long> idScope = idWorker.getIdScopeByTimestamp(createTimestamp, createTimestamp, ignore);
|
||||
final long startId = idScope.getLeft();
|
||||
final long endId = idScope.getRight();
|
||||
|
||||
// 起点终点相差比较
|
||||
final long trueOffSet = endId - startId;
|
||||
// 忽略数据中心和工作机器时差值为22个1,否则为12个1
|
||||
final long expectedOffSet = ignore ? ~(-1 << 22) : ~(-1 << 12);
|
||||
Assertions.assertEquals(trueOffSet, expectedOffSet);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user