content: 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;
  	}
  
  }
  