package com.alimama.mdrill.solr.hbaserealtime.queue.client;
import java.text.DecimalFormat;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.util.Bytes;
/**
* 同一个shard的同一个分区 必须在同一个进程内生成,否则这个messageId不会保证全局递增唯一
* 之所以没有考虑借助外部生成全局唯一ID,主要考虑的是性能因数,大家可以通过改动INSTANCE的方法自己实现
* @author yannian.mu
*
*/
public class MessageID implements java.lang.Comparable<MessageID> {
private static long CURR_TS=-1;
private static short CURR_SUBINDEX=-1;
public static synchronized MessageID INSTANCE(short shardIndex, long partioncrc,Configuration realConf)
{
long ts=System.currentTimeMillis();
if(ts!=CURR_TS)
{
CURR_TS=ts;
CURR_SUBINDEX=0;
}
return new MessageID(shardIndex, partioncrc,CURR_TS, CURR_SUBINDEX++);
}
public static String MAKE_PARTERN(String partion)
{
StringBuffer buffer = new StringBuffer(partion.length());
for (int i = 0; i < partion.length(); i++) {
buffer.append("0");
}
return buffer.toString();
}
private static String SHORT_PATTERN=MAKE_PARTERN(String.valueOf(Short.MAX_VALUE));
private static String lONG_PATTERN=MAKE_PARTERN(String.valueOf(Long.MAX_VALUE));
public static DecimalFormat SHORT_Format = new DecimalFormat(SHORT_PATTERN);
public static DecimalFormat LONG_Format = new DecimalFormat(lONG_PATTERN);
private short shard;
private long partion;
private long index;
private short subIndex;
public static byte[] toBytes(MessageID msgid)
{
StringBuffer buff=new StringBuffer();
buff.append(SHORT_Format.format(msgid.getShardIndex()));
buff.append(LONG_Format.format(msgid.getPartioncrc()));
buff.append(LONG_Format.format(msgid.getIndex()));
buff.append(SHORT_Format.format(msgid.getSubIndex()));
return Bytes.toBytes(buff.toString());
}
public MessageID(short shardIndex, long partioncrc, long index, short subindex) {
this.shard = shardIndex;
this.partion = partioncrc;
this.index = index;
this.subIndex = subindex;
}
public long getPartioncrc() {
return partion;
}
public short getShardIndex() {
return shard;
}
public long getIndex() {
return index;
}
public short getSubIndex() {
return subIndex;
}
public int compareTo(MessageID other) {
if (this.shard != other.shard) {
return this.shard > other.shard ? 1 : -1;
}
if (this.partion != other.partion) {
return this.partion > other.partion ? 1 : -1;
}
if (this.index != other.index) {
return this.index > other.index ? 1 : -1;
}
if (this.subIndex != other.subIndex) {
return this.subIndex > other.subIndex ? 1 : -1;
} else {
return 0;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (index ^ (index >>> 32));
result = prime * result + (int) (partion ^ (partion >>> 32));
result = prime * result + shard;
result = prime * result + subIndex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MessageID other = (MessageID) obj;
if (index != other.index)
return false;
if (partion != other.partion)
return false;
if (shard != other.shard)
return false;
if (subIndex != other.subIndex)
return false;
return true;
}
}