package org.molgenis.util;
import com.eaio.uuid.UUIDGen;
import java.nio.ByteBuffer;
/**
* Copied from https://github.com/mumrah/flake-java/blob/master/src/uniq/UniqueId.java
* <p>
* See also http://boundary.com/blog/2012/01/12/flake-a-decentralized-k-ordered-unique-id-generator-in-erlang/
*/
public class UniqueId
{
// Get the MAC address (i.e., the "node" from a UUID1)
private final long clockSeqAndNode = UUIDGen.getClockSeqAndNode();
private final byte[] node = new byte[] { (byte) ((clockSeqAndNode >> 40) & 0xff),
(byte) ((clockSeqAndNode >> 32) & 0xff), (byte) ((clockSeqAndNode >> 24) & 0xff),
(byte) ((clockSeqAndNode >> 16) & 0xff), (byte) ((clockSeqAndNode >> 8) & 0xff),
(byte) ((clockSeqAndNode) & 0xff), };
private final ThreadLocal<ByteBuffer> tlbb = new ThreadLocal<ByteBuffer>()
{
@Override
public ByteBuffer initialValue()
{
return ByteBuffer.allocate(16);
}
};
private volatile int seq;
private volatile long lastTimestamp;
private final Object lock = new Object();
private final int maxShort = 0xffff;
public byte[] getId()
{
if (seq == maxShort)
{
throw new RuntimeException("Too fast");
}
long time;
synchronized (lock)
{
time = System.currentTimeMillis();
if (time != lastTimestamp)
{
lastTimestamp = time;
seq = 0;
}
seq++;
ByteBuffer bb = tlbb.get();
bb.rewind();
bb.putLong(time);
bb.put(node);
bb.putShort((short) seq);
return bb.array();
}
}
}