
net.apexes.commons.lang.IDGenerator Maven / Gradle / Ivy
/*
* Copyright (c) 2018, apexes.net. All rights reserved.
*
* http://www.apexes.net
*
*/
package net.apexes.commons.lang;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.BitSet;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
/**
*
* @author HeDYn
*/
public class IDGenerator {
private final byte[] idedBytes;
private IDGenerator(byte[] idedBytes) {
this.idedBytes = idedBytes;
}
public String gen() {
return IDGenerator.genId(idedBytes);
}
private static final AtomicLong LAST_TIME = new AtomicLong(Long.MIN_VALUE);
private static final Ided IDED = new Ided();
static String genId() {
return genId(IDED.systemIdedBytes());
}
static String genId(byte[] idedBytes) {
ByteBuffer buf = ByteBuffer.allocate(16);
buf.putLong(timeMillis());
buf.put(idedBytes);
return IDs.toBase58Id(buf.array());
}
private static long timeMillis() {
long timeMillis = System.currentTimeMillis();
// 每毫秒最多8192个
timeMillis <<= 13;
while (true) {
long current = LAST_TIME.get();
if (timeMillis > current) {
if (LAST_TIME.compareAndSet(current, timeMillis)) {
break;
}
} else {
if (LAST_TIME.compareAndSet(current, current + 1)) {
timeMillis = current + 1;
break;
}
}
}
return timeMillis;
}
static IDGenerator namespace(long namespace) {
return new IDGenerator(Bytes.longToBytes(namespace));
}
static IDGenerator namespace(int major, short minor) {
byte[] majorBytes = Bytes.intToBytes(major);
byte[] minorBytes = Bytes.shortToBytes(minor);
byte[] pidBytes = IDED.pidBytes();
byte[] namespaceBytes = new byte[8];
namespaceBytes[0] = pidBytes[0];
namespaceBytes[1] = pidBytes[1];
namespaceBytes[2] = minorBytes[0];
namespaceBytes[3] = minorBytes[1];
namespaceBytes[4] = majorBytes[0];
namespaceBytes[5] = majorBytes[1];
namespaceBytes[6] = majorBytes[2];
namespaceBytes[7] = majorBytes[3];
return new IDGenerator(namespaceBytes);
}
private static class Ided {
private volatile byte[] pidBytes;
private volatile byte[] systemIdedBytes;
private Ided() {
}
byte[] pidBytes() {
if (pidBytes == null) {
synchronized (Ided.class) {
if (pidBytes == null) {
init();
}
}
}
return pidBytes;
}
byte[] systemIdedBytes() {
if (systemIdedBytes == null) {
synchronized (Ided.class) {
if (systemIdedBytes == null) {
init();
}
}
}
return systemIdedBytes;
}
private void init() {
short pid = ProcessIdentifier.Impl.processId();
Long macValue = Networks.macValue();
if (macValue == null) {
try {
byte[] localBytes = InetAddress.getLocalHost().getAddress();
int localValue = Bytes.bytesToInt(localBytes);
macValue = (long) localValue;
macValue <<= 8;
} catch (Exception e) {
Random random = new Random(System.currentTimeMillis());
macValue = random.nextLong();
}
}
BitSet bitSet = new BitSet(64);
long m = 1;
for (int i = 0; i < 16; i++) {
if ((pid & m) != 0) {
bitSet.set(i * 4);
}
m <<= 1;
}
m = 1;
for (int i =0; i < 48; i++) {
if ((macValue & m) != 0) {
bitSet.set(i + (i / 3) + 1);
}
m <<= 1;
}
systemIdedBytes = bitSet.toByteArray();
pidBytes = Bytes.shortToBytes(pid);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy