package com.taobao.tddl.atom.utils;
import java.util.Arrays;
import com.taobao.tddl.common.utils.TStringUtil;
/**
* 应用连接数限制功能中的连接数配置。
*
* @author changyuan.lh
*/
public final class ConnRestrictEntry {
/**
* HASH 策略的最大槽数量限制。
*/
public static final int MAX_HASH_RESTRICT_SLOT = 32;
protected final String[] keys;
protected int hashSize;
protected int limits;
public ConnRestrictEntry(String[] keys, int hashSize, int limits){
this.keys = keys;
this.hashSize = hashSize;
this.limits = limits;
}
public String[] getKeys() {
return keys;
}
public void setHashSize(int hashSize) {
this.hashSize = hashSize;
}
public int getHashSize() {
return hashSize;
}
public void setLimits(int limits) {
this.limits = limits;
}
public int getLimits() {
return limits;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + limits;
result = prime * result + hashSize;
result = prime * result + Arrays.hashCode(keys);
return result;
}
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
ConnRestrictEntry other = (ConnRestrictEntry) obj;
if (limits != other.limits) return false;
if (hashSize != other.hashSize) return false;
if (!Arrays.equals(keys, other.keys)) return false;
return true;
}
public String toString() {
return "ConnRestrictEntry: " + Arrays.toString(keys) + " " + hashSize + ", " + limits;
}
protected static final String KEY_DEFAULT = "~"; // 匹配 null Key
protected static final String KEY_WILDCARD = "*"; // 匹配所有 Key
protected static final String PERCENT = "%"; // 百分比
public static boolean isNullKey(String key) {
return KEY_DEFAULT.equals(key);
}
public static boolean isWildcard(String key) {
return KEY_WILDCARD.equals(key);
}
/**
* Parse "K1,K2,K3:number | *:count,number | ~:number"
*/
public static ConnRestrictEntry parseEntry(String key, String value, int maxPoolSize) {
if (key == null || value == null) {
return null;
}
if (KEY_WILDCARD.equals(key)) {
// Parse "*:count,number"
int find = value.indexOf(',');
if (find >= 0) {
String countStr = value.substring(0, find).trim();
String numberStr = value.substring(find + 1).trim();
if (countStr.isEmpty()) {
// Parse "*:,number"
if (numberStr.endsWith(PERCENT)) {
numberStr = TStringUtil.substringBefore(numberStr, PERCENT);
if (TStringUtil.isNumeric(numberStr)) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(new String[] { key },
1,
maxPoolSize * Integer.valueOf(numberStr) / 100);
return connRestrictEntry;
}
} else if (TStringUtil.isNumeric(numberStr)) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(new String[] { key },
1,
Integer.valueOf(numberStr));
return connRestrictEntry;
}
} else if (TStringUtil.isNumeric(countStr)) {
// Parse "*:count,number"
if (numberStr.endsWith(PERCENT)) {
numberStr = TStringUtil.substringBefore(numberStr, PERCENT);
if (TStringUtil.isNumeric(numberStr)) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(new String[] { key },
Integer.valueOf(countStr),
maxPoolSize * Integer.valueOf(numberStr) / 100);
return connRestrictEntry;
}
} else if (TStringUtil.isNumeric(numberStr)) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(new String[] { key },
Integer.valueOf(countStr),
Integer.valueOf(numberStr));
return connRestrictEntry;
}
}
} else {
// Parse "*:number"
if (value.endsWith(PERCENT)) {
String numberStr = TStringUtil.substringBefore(value, PERCENT);
if (TStringUtil.isNumeric(numberStr)) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(new String[] { key },
1,
maxPoolSize * Integer.valueOf(numberStr) / 100);
return connRestrictEntry;
}
} else if (TStringUtil.isNumeric(value)) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(new String[] { key },
1,
Integer.valueOf(value));
return connRestrictEntry;
}
}
} else if (KEY_DEFAULT.equals(key)) {
// Parse "~:number"
if (value.endsWith(PERCENT)) {
String numberStr = TStringUtil.substringBefore(value, PERCENT);
if (TStringUtil.isNumeric(numberStr)) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(new String[] { key },
1,
maxPoolSize * Integer.valueOf(numberStr) / 100);
return connRestrictEntry;
}
} else if (TStringUtil.isNumeric(value)) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(new String[] { key },
1,
Integer.valueOf(value));
return connRestrictEntry;
}
} else {
// Parse "K1,K2,K3:number"
if (value.endsWith(PERCENT)) {
String numberStr = TStringUtil.substringBefore(value, PERCENT);
if (TStringUtil.isNumeric(numberStr)) {
String[] keys = TStringUtil.split(key, ",");
if (null != keys && keys.length > 0) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(keys,
1,
maxPoolSize * Integer.valueOf(numberStr) / 100);
return connRestrictEntry;
}
}
} else if (TStringUtil.isNumeric(value)) {
String[] keys = TStringUtil.split(key, ",");
if (null != keys && keys.length > 0) {
ConnRestrictEntry connRestrictEntry = new ConnRestrictEntry(keys, 1, Integer.valueOf(value));
return connRestrictEntry;
}
}
}
return null;
}
}