All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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