blob: 55d8cda9715bab2cc8aa7b07c4dbbfdc8532ec6e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.remoting.internal;
import java.nio.ByteBuffer;
import java.util.Calendar;
public class UIDGenerator {
private static ThreadLocal<UIDGenerator> generatorLocal = new ThreadLocal<UIDGenerator>() {
@Override
protected UIDGenerator initialValue() {
return new UIDGenerator();
}
};
private short counter;
private int basePos = 0;
private long startTime;
private long nextStartTime;
private StringBuilder sb = null;
private ByteBuffer buffer = ByteBuffer.allocate(6);
private UIDGenerator() {
int len = 4 + 2 + 4 + 4 + 2;
sb = new StringBuilder(len * 2);
ByteBuffer tempBuffer = ByteBuffer.allocate(len - buffer.limit());
tempBuffer.position(2);
tempBuffer.putInt(JvmUtils.getProcessId());
tempBuffer.position(0);
try {
tempBuffer.put((byte) 1);
} catch (Exception e) {
tempBuffer.put(createFakeIP());
}
tempBuffer.position(6);
tempBuffer.putInt(UIDGenerator.class.getClassLoader().hashCode());
sb.append(ByteUtils.toHexString(tempBuffer.array()));
basePos = sb.length();
setStartTime(System.currentTimeMillis());
counter = 0;
}
public static UIDGenerator instance() {
return generatorLocal.get();
}
public byte[] createFakeIP() {
ByteBuffer bb = ByteBuffer.allocate(8);
bb.putLong(System.currentTimeMillis());
bb.position(4);
byte[] fakeIP = new byte[4];
bb.get(fakeIP);
return fakeIP;
}
private void setStartTime(long millis) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
startTime = cal.getTimeInMillis();
cal.add(Calendar.MONTH, 1);
nextStartTime = cal.getTimeInMillis();
}
public String createUID() {
long current = System.currentTimeMillis();
if (current >= nextStartTime) {
setStartTime(current);
}
buffer.position(0);
sb.setLength(basePos);
buffer.putInt((int) (System.currentTimeMillis() - startTime));
buffer.putShort(counter++);
sb.append(ByteUtils.toHexString(buffer.array()));
return sb.toString();
}
}