Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2017 Baidu, Inc. All Rights Reserve.
*
* Licensed 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 com.baidu.fsg.uid.impl;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import com.baidu.fsg.uid.BitsAllocator;
import com.baidu.fsg.uid.UidGenerator;
import com.baidu.fsg.uid.exception.UidGenerateException;
import com.baidu.fsg.uid.utils.DateUtils;
import com.baidu.fsg.uid.worker.WorkerIdAssigner;
public class DefaultUidGenerator implements UidGenerator, InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultUidGenerator.class);
protected int timeBits = 28;
protected int workerBits = 22;
protected int seqBits = 13;
protected String epochStr = "2016-05-20";
protected long epochSeconds = TimeUnit.MILLISECONDS.toSeconds(1463673600000L);
protected BitsAllocator bitsAllocator;
protected long workerId;
protected long sequence = 0L;
protected long lastSecond = -1L;
protected WorkerIdAssigner workerIdAssigner;
@Override
public void afterPropertiesSet() throws Exception {
// initialize bits allocator
bitsAllocator = new BitsAllocator(timeBits, workerBits, seqBits);
// initialize worker id
workerId = workerIdAssigner.assignWorkerId();
if (workerId > bitsAllocator.getMaxWorkerId()) {
throw new RuntimeException("Worker id " + workerId + " exceeds the max " + bitsAllocator.getMaxWorkerId());
}
LOGGER.info("Initialized bits(1, {}, {}, {}) for workerID:{}", timeBits, workerBits, seqBits, workerId);
}
@Override
public long getUID() throws UidGenerateException {
try {
return nextId();
} catch (Exception e) {
LOGGER.error("Generate unique id exception. ", e);
throw new UidGenerateException(e);
}
}
@Override
public String parseUID(long uid) {
long totalBits = BitsAllocator.TOTAL_BITS;
long signBits = bitsAllocator.getSignBits();
long timestampBits = bitsAllocator.getTimestampBits();
long workerIdBits = bitsAllocator.getWorkerIdBits();
long sequenceBits = bitsAllocator.getSequenceBits();
// parse UID
long sequence = (uid << (totalBits - sequenceBits)) >>> (totalBits - sequenceBits);
long workerId = (uid << (timestampBits + signBits)) >>> (totalBits - workerIdBits);
long deltaSeconds = uid >>> (workerIdBits + sequenceBits);
Date thatTime = new Date(TimeUnit.SECONDS.toMillis(epochSeconds + deltaSeconds));
String thatTimeStr = DateUtils.formatByDateTimePattern(thatTime);
// format as string
return String.format("{\"UID\":\"%d\",\"timestamp\":\"%s\",\"workerId\":\"%d\",\"sequence\":\"%d\"}",
uid, thatTimeStr, workerId, sequence);
}
protected synchronized long nextId() {
long currentSecond = getCurrentSecond();
// Clock moved backwards, refuse to generate uid
if (currentSecond < lastSecond) {
long refusedSeconds = lastSecond - currentSecond;
throw new UidGenerateException("Clock moved backwards. Refusing for %d seconds", refusedSeconds);
}
// At the same second, increase sequence
if (currentSecond == lastSecond) {
sequence = (sequence + 1) & bitsAllocator.getMaxSequence();
// Exceed the max sequence, we wait the next second to generate uid
if (sequence == 0) {
currentSecond = getNextSecond(lastSecond);
}
// At the different second, sequence restart from zero
} else {
sequence = 0L;
}
lastSecond = currentSecond;
// Allocate bits for UID
return bitsAllocator.allocate(currentSecond - epochSeconds, workerId, sequence);
}
private long getNextSecond(long lastTimestamp) {
long timestamp = getCurrentSecond();
while (timestamp <= lastTimestamp) {
timestamp = getCurrentSecond();
}
return timestamp;
}
private long getCurrentSecond() {
long currentSecond = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
if (currentSecond - epochSeconds > bitsAllocator.getMaxDeltaSeconds()) {
throw new UidGenerateException("Timestamp bits is exhausted. Refusing UID generate. Now: " + currentSecond);
}
return currentSecond;
}
public void setWorkerIdAssigner(WorkerIdAssigner workerIdAssigner) {
this.workerIdAssigner = workerIdAssigner;
}
public void setTimeBits(int timeBits) {
if (timeBits > 0) {
this.timeBits = timeBits;
}
}
public void setWorkerBits(int workerBits) {
if (workerBits > 0) {
this.workerBits = workerBits;
}
}
public void setSeqBits(int seqBits) {
if (seqBits > 0) {
this.seqBits = seqBits;
}
}
public void setEpochStr(String epochStr) {
if (StringUtils.isNotBlank(epochStr)) {
this.epochStr = epochStr;
this.epochSeconds = TimeUnit.MILLISECONDS.toSeconds(DateUtils.parseByDayPattern(epochStr).getTime());
}
}
}