
com.sghd.common.utils.id.account.AccountIdGenerator Maven / Gradle / Ivy
The newest version!
package com.sghd.common.utils.id.account;
import java.util.concurrent.atomic.AtomicLong;
/**
* 主键生成器
* [保留位:6][运营商:2][服务器位:3][主键自增位:5]
*/
public class AccountIdGenerator {
public static final int OP_MV = 32;
public static final int ARE_MV = 20;
/** 运营商标识 */
private final short operator;
/** 服务器标识 */
private final short area;
/** 当前自增值 */
private final AtomicLong current;
/** 溢出边界 */
private final long limit;
/**
* 构造主键生成器
* @param operator 运营商标识
* @param area 服务器标识
* @param current 当前的主键值
*/
public AccountIdGenerator(short operator, short area, Long current) {
if (!vaildValue(operator, 8)) {
throw new IllegalArgumentException("运营商标识[" + operator + "]超过了12位二进制数的表示范围");
}
if (!vaildValue(area, 12)) {
throw new IllegalArgumentException("服务器标识[" + area + "]超过了12位二进制数的表示范围");
}
this.operator = operator;
this.area = area;
final long[] limits = getLimits(operator, area);
if (current != null) {
if (current < limits[0] || current > limits[1]) {
throw new IllegalArgumentException("当前主键值[" + current + "],不符合运营商标识[" + operator + "]服务器标识[" + area
+ "]的要求");
}
this.current = new AtomicLong(current);
} else {
this.current = new AtomicLong(limits[0]);
}
this.limit = limits[1];
}
/**
* 获取当前的主键值
* @return
*/
public long getCurrent() {
return current.get();
}
/**
* 获取下一个主键值
* @return
* @throws IllegalStateException 到达边界值时会抛出该异常
*/
public long getNext() {
long result = current.incrementAndGet();
if (result > limit) {
throw new IllegalStateException("主键值[" + result + "]已经超出了边界[" + limit + "]");
}
return result;
}
// Getter and Setter ...
public short getArea() {
return area;
}
public short getOperator() {
return operator;
}
public int getServerId(){
return toServerId(operator, area);
}
public long getLimit() {
return limit;
}
// Static Method's ...
/**
* 获取主键中的服标识
* @param id 主键值
* @return
*/
public static short toArea(long id) {
if ((0xFFFFFF0000000000L & id) != 0) {
throw new IllegalArgumentException("无效的ID标识值:" + id);
}
// 将高位置0(保留位+运营商位+服务器位)
return (short) ((id >> 20) & 0x0000000000000FFFL);
}
public static short toArea(int serverId){
return (short) ((serverId) & 0x00000FFF);
}
/**
* 获取主键中的运营商标识
* @param id 主键值
* @return
*/
public static short toOperator(long id) {
if ((0xFFFFFF0000000000L & id) != 0) {
throw new IllegalArgumentException("无效的ID标识值:" + id);
}
// 将高位置0(保留位+运营商位+服务器位)
return (short) ((id >> 32) & 0x00000000000000FFL);
}
public static short toOperator(int serverId){
if(serverId < 0){
return (short)serverId;
}
return (short) ((serverId >> 12) & 0x000000FF);
}
public static int toServerId(long playerId){
PlayerIdInfo info = new PlayerIdInfo(playerId);
return info.server;
}
public static int toServerId(short operator, short area){
return (operator << 12) + area;
}
public static short serverId2Area(int serverId){
return (short) (serverId & 0x00000FFF);
}
public static short serverId2Operator(int serverId){
return (short) ((serverId >> 12) & 0x000000FF);
}
public static int[] toServerLimits(short operator){
int min = (operator << 12) + 1;
int max = (operator << 12) + 0xFFF;
return new int[]{min, max};
}
public static void main(String[] args) {
System.out.println(toOperator(4097));
System.out.println(toOperator(1));
System.out.println(toArea(1));
System.out.println(toArea(1));
System.out.println(Long.toString(121212121212l, 32).toUpperCase());
}
// /**
// * 检查值是否超过 byte 的表示范围
// * @param value 被检查的值
// * @return true:合法,false:非法或超过范围
// */
// public static boolean vaildByteValue(short value) {
// if (value >= 0 && value <= 255) {
// return true;
// }
// return false;
// }
/**
* 检查值是否超过指定位数的2进制表示范围
* @param value 被检查的值
* @param digit 2进制位数
* @return true:合法,false:非法或超过范围
*/
public static boolean vaildValue(short value, int digit) {
if (digit <= 0 || digit > 64) {
throw new IllegalArgumentException("位数必须在1-64之间");
}
int max = (1 << digit) - 1;
if (value >= 0 && value <= max) {
return true;
}
return false;
}
/**
* 获取ID值边界
* @param operator 运营商值
* @param area 服务器值
* @return [0]:最小值,[1]:最大值
*/
public static long[] getLimits(short operator, short area) {
long min = getMini(operator, area);
long max = min | 0x00000000000FFFFFL;
return new long[] { min, max };
}
/**
* 获取ID值边界
* @param operator 运营商值
* @return [0]:最小值,[1]:最大值
*/
public static long[] getLimits(short operator) {
if (!vaildValue(operator, 8)) {
throw new IllegalArgumentException("运营商标识[" + operator + "]超过了12位二进制数的表示范围");
}
long min = (((long) operator) << 48);
long max = min | 0x00000000FFFFFFFFL;
return new long[] { min, max };
}
public static long getMini(short operator, short area){
if (!vaildValue(operator, 8)) {
throw new IllegalArgumentException("运营商标识[" + operator + "]超过了12位二进制数的表示范围");
}
if (!vaildValue(area, 12)) {
throw new IllegalArgumentException("服务器标识[" + area + "]超过了12位二进制数的表示范围");
}
long min = (((long) operator) << 32) + (((long) area) << 20);
return min;
}
/** ID信息 */
public static class PlayerIdInfo {
/** 运营商标识 */
private final short operator;
/** 服务器标识 */
private final short area;
/** 标识 */
private final long id;
/**游戏服serverId*/
private final int server;
/** 构造方法 */
public PlayerIdInfo(long id) {
if ((0xF000000000000000L & id) != 0) {
throw new IllegalArgumentException("无效的ID标识值:" + id);
}
this.id = id & 0x00000000000FFFFFL; // 将高位置0(保留位+运营商位+服务器位)
this.area = (short) ((id >> 20) & 0x0000000000000FFFL);
this.operator = (short) ((id >> 32) & 0x00000000000000FFL);
this.server = toServerId(operator, area);
}
// Getter and Setter ...
/**
* 获取服务器标识值
* @return
*/
public short getArea() {
return area;
}
/**
* 获取运营商标识值
* @return
*/
public short getOperator() {
return operator;
}
/**
* 获取去除运营商标识和服务器标识的ID值
* @return
*/
public long getId() {
return id;
}
public int getServer() {
return server;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy