![JAR search and dependency download from the Maven repository](/logo.png)
rpc.turbo.util.uuid.RandomId Maven / Gradle / Ivy
package rpc.turbo.util.uuid;
import static java.time.ZoneOffset.UTC;
import static rpc.turbo.util.HexUtils.byteToHexLE;
import static rpc.turbo.util.UnsafeUtils.unsafe;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Objects;
import io.netty.buffer.ByteBuf;
import io.netty.util.internal.ThreadLocalRandom;
import rpc.turbo.util.SystemClock;
import rpc.turbo.util.UnsafeStringUtils;
import rpc.turbo.util.concurrent.ThreadLocalBytes;
/**
*
* A globally unique identifier for objects.
*
*
*
* Consists of 12 bytes, divided as follows:
*
*
* RandomId layout
*
* 0
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
*
*
* time
* random long
*
*
*
*
* Instances of this class are immutable.
*
*
*/
public final class RandomId implements Serializable {
private static final long serialVersionUID = -2951994548246899462L;
private static final long HEX32_PADDING = ByteBuffer.wrap("0000000000000000".getBytes()).getLong();
public final static long OFFSET_SECONDS = LocalDateTime.parse("2018-01-01T00:00:00").toEpochSecond(UTC);
public final int timestamp;
public final long random;
/**
* Gets a new object id.
*
* @return the new id
*/
public static RandomId next() {
return new RandomId(currentSeconds(), ThreadLocalRandom.current().nextLong());
}
public RandomId(final int timestamp, final long random) {
this.timestamp = timestamp;
this.random = random;
}
public RandomId(final ByteBuf buffer) {
Objects.requireNonNull(buffer, "buffer");
timestamp = buffer.readInt();
random = buffer.readLong();
}
public int getTimestamp() {
return timestamp;
}
public long getRandom() {
return random;
}
public void writeTo(final ByteBuf buffer) {
buffer.writeInt(timestamp);
buffer.writeLong(random);
}
public String toHexStringOld() {
// java8 下更高效
byte[] bytes = ThreadLocalBytes.current();
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 0, byteToHexLE(timestamp >> 24));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 2, byteToHexLE(timestamp >> 16));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 4, byteToHexLE(timestamp >> 8));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 6, byteToHexLE(timestamp));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 8, byteToHexLE(random >> 52));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 10, byteToHexLE(random >> 48));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 12, byteToHexLE(random >> 40));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 14, byteToHexLE(random >> 32));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 16, byteToHexLE(random >> 24));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 18, byteToHexLE(random >> 16));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 20, byteToHexLE(random >> 8));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 22, byteToHexLE(random));
String hex = new String(bytes, 0, 24, StandardCharsets.ISO_8859_1);
return hex;
}
public String toHexString() {
// java9 下更高效
byte[] bytes = new byte[24];
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 0, byteToHexLE(timestamp >> 24));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 2, byteToHexLE(timestamp >> 16));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 4, byteToHexLE(timestamp >> 8));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 6, byteToHexLE(timestamp));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 8, byteToHexLE(random >> 52));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 10, byteToHexLE(random >> 48));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 12, byteToHexLE(random >> 40));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 14, byteToHexLE(random >> 32));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 16, byteToHexLE(random >> 24));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 18, byteToHexLE(random >> 16));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 20, byteToHexLE(random >> 8));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 22, byteToHexLE(random));
String hex = UnsafeStringUtils.toLatin1String(bytes);
return hex;
}
/**
* 128位编码, 长度为32, 前8个字符用'0'填充
*
* @return
*/
public String toHexString32() {
byte[] bytes = new byte[32];
unsafe().putLong(bytes, ARRAY_BYTE_BASE_OFFSET, HEX32_PADDING);
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 0 + 8, byteToHexLE(timestamp >> 24));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 2 + 8, byteToHexLE(timestamp >> 16));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 4 + 8, byteToHexLE(timestamp >> 8));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 6 + 8, byteToHexLE(timestamp));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 8 + 8, byteToHexLE(random >> 52));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 10 + 8, byteToHexLE(random >> 48));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 12 + 8, byteToHexLE(random >> 40));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 14 + 8, byteToHexLE(random >> 32));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 16 + 8, byteToHexLE(random >> 24));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 18 + 8, byteToHexLE(random >> 16));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 20 + 8, byteToHexLE(random >> 8));
unsafe().putShort(bytes, ARRAY_BYTE_BASE_OFFSET + 22 + 8, byteToHexLE(random));
String hex = UnsafeStringUtils.toLatin1String(bytes);
return hex;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (random ^ (random >>> 32));
result = prime * result + timestamp;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RandomId other = (RandomId) obj;
if (random != other.random)
return false;
if (timestamp != other.timestamp)
return false;
return true;
}
@Override
public String toString() {
return toHexString();
}
private static int currentSeconds() {
return (int) (SystemClock.fast().seconds() - OFFSET_SECONDS);
}
public static void main(String[] args) {
RandomId id = RandomId.next();
System.out.println(id.toHexString());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy