// Copyright (C) 2015 anduo
// All rights reserved
package com.anduo.nz.zk;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
/**
* ━━━━━━神兽出没━━━━━━
* ┏┓ ┏┓
* ┏┛┻━━━┛┻┓
* ┃ ┃
* ┃ ━ ┃
* ┃ ┳┛ ┗┳ ┃
* ┃ ┃
* ┃ ┻ ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃神兽保佑, 永无BUG!
* ┃ ┃Code is far away from bug with the animal protecting
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
* ━━━━━━感觉萌萌哒━━━━━━
* Summary: TODO 描述信息
* Author : anduo@qq.com
* Version: 1.0
* Date : 15/7/2
* time : 01:11
*/
public class ClientNodes extends CommonNodes{
protected static Logger logger = LoggerFactory.getLogger(ServerNodes.class);
protected HashMap<String, BasicDBObject> recordsById = new HashMap();
protected HashMap<String, BasicDBList> recordsByJobClass = new HashMap();
protected BasicDBList records = new BasicDBList();
protected HashSet<String> jobClassSet = new HashSet();
public BasicDBObject hashClient(String jobClass, String hashKey) {
BasicDBList items = getRecordsByJobClass(jobClass);
if ((items == null) || (items.size() == 0)) {
return null;
}
if (StringUtils.isEmpty(hashKey)) {
hashKey = allocateNo();
}
int index = HashTimes.use33(hashKey) % items.size();
return (BasicDBObject) items.get(index);
}
/**
* hashClient升级版本(4S==For Super)
* @param jobClass
* @param hashKey
* @return
*/
public Map hashClient4S(String jobClass, String hashKey) {
Map map = new HashMap();
BasicDBList items = getRecordsByJobClass(jobClass);
if ((items == null) || (items.size() == 0)) {
map.put(CommonConstants.SUCCESS, false);
map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);
return map;
}
if (StringUtil.isEmpty(hashKey)) {
hashKey = allocateNo();
}
int index = HashTimes.use33(hashKey) % items.size();
map.put(CommonConstants.SUCCESS, true);
map.put(CommonConstants.CLIENT_JOB_INFO, items.get(index));
return map;
}
public BasicDBObject hashClientByFixedClientIps(String jobClass, String[] fixedClientIps) {
BasicDBList items = getRecordsByJobClass(jobClass);
if ((items == null) || (items.size() == 0)) {
return null;
}
int index = -1;
for (String fixedClientIp : fixedClientIps) {
index = findIndexByIp(fixedClientIp, items);
if (index == -1) continue;
}
if (index == -1) {
return null;
}
return (BasicDBObject) items.get(index);
}
/**
* hashClientByFixedClientIps升级版本(4S==For Super)
* @param jobClass
* @param fixedClientIps
* @return
*/
public Map hashClient4SByFixedClientIps(String jobClass, String[] fixedClientIps) {
Map map = new HashMap();
BasicDBList items = getRecordsByJobClass(jobClass);
if ((items == null) || (items.size() == 0)) {
map.put(CommonConstants.SUCCESS, false);
map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);
}
int index = -1;
for (String fixedClientIp : fixedClientIps) {
index = findIndexByIp(fixedClientIp, items);
if (index == -1) continue;
}
if (index == -1) {
map.put(CommonConstants.SUCCESS, false);
map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);
}
map.put(CommonConstants.SUCCESS, true);
map.put(CommonConstants.CLIENT_JOB_INFO, items.get(index));
return map;
}
public BasicDBObject hashClientBySystemCapacity(String jobClass) {
BasicDBList items = getRecordsByJobClass(jobClass);
int itemLen;
if ((items == null) || ((itemLen = items.size()) == 0)) {
return null;
} else if (1 == itemLen) {
BasicDBObject item = (BasicDBObject) items.get(0);
double memRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.MEM_RATIO)));
double cpuRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.CPU_RATIO)));
if (memRatio > CommonConstants.MAX_MEM_RATIO || cpuRatio > CommonConstants.MAX_CPU_RATIO ) {
logger.error("ClientNodes-->>hashClientBySystemCapacity(" + jobClass + ") the memRatio(" + memRatio + ")" +
" over max mem ratio("+CommonConstants.MAX_MEM_RATIO+") or the cpuRatio("+cpuRatio+") " +
"over max cpu ratio("+CommonConstants.MAX_CPU_RATIO+") ");
return null;
} else {
return item;
}
} else if (itemLen > 1) {
BasicDBObject tempItem = (BasicDBObject) items.get(0);
int minMemRatioIndex = 0;
double minMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));
double minCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));
int minTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));
double minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;
for (int i = 1; i < itemLen; i++) {
tempItem = (BasicDBObject) items.get(i);
double tempMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));
double tempCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));
int tempTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));
double tempTotalValue = tempMemRatioValue + tempCpuRatioValue + tempTotalThreadValue;
if (tempTotalValue < minTotalValue) {
minMemRatioValue = tempMemRatioValue;
minCpuRatioValue = tempCpuRatioValue;
minTotalThreadValue = tempTotalThreadValue;
minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;
minMemRatioIndex = i;
}
}
if (minMemRatioValue > CommonConstants.MAX_MEM_RATIO || minCpuRatioValue > CommonConstants.MAX_CPU_RATIO) {
logger.error("ClientNodes-->>hashClientBySystemCapacity(" + jobClass + ") " +
"the memRatio(" + minMemRatioValue + ") over max mem ratio(" + CommonConstants.MAX_MEM_RATIO + ")" +
"or the cpuRatio("+minCpuRatioValue+") over max cpu ration ("+CommonConstants.MAX_CPU_RATIO+") ");
return null;
} else {
return (BasicDBObject) items.get(minMemRatioIndex);
}
}
return null;
}
/**
* hashClientBySystemCapacity升级版本(4S==For Super)
*
* @param jobClass
* @return
*/
public Map hashClient4SBySystemCapacity(String jobClass) {
Map map = new HashMap();
BasicDBList items = getRecordsByJobClass(jobClass);
int itemLen;
if ((items == null) || ((itemLen = items.size()) == 0)) {
map.put(CommonConstants.SUCCESS, false);
map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_101);
return map;
} else if (1 == itemLen) {
BasicDBObject item = (BasicDBObject) items.get(0);
double memRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.MEM_RATIO)));
double cpuRatio = Double.valueOf(String.valueOf(item.get(CommonConstants.CPU_RATIO)));
if (memRatio > CommonConstants.MAX_MEM_RATIO || cpuRatio > CommonConstants.MAX_CPU_RATIO) {
logger.error("ClientNodes-->>hashClient4SBySystemCapacity(" + jobClass + ") the memRatio(" + memRatio + ")" +
" over max mem ratio(" + CommonConstants.MAX_MEM_RATIO + ") or the cpuRatio("+cpuRatio+")" +
" over max cpu ratio("+CommonConstants.MAX_CPU_RATIO+") ");
map.put(CommonConstants.SUCCESS, false);
map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_102);
map.put(CommonConstants.MEM_RATIO, memRatio);
map.put(CommonConstants.CPU_RATIO, cpuRatio);
return map;
} else {
map.put(CommonConstants.SUCCESS, true);
map.put(CommonConstants.CLIENT_JOB_INFO, item);
return map;
}
} else if (itemLen > 1) {
BasicDBObject tempItem = (BasicDBObject) items.get(0);
int minMemRatioIndex = 0;
double minMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));
double minCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));
int minTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));
double minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;
for (int i = 1; i < itemLen; i++) {
tempItem = (BasicDBObject) items.get(i);
double tempMemRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.MEM_RATIO)));
double tempCpuRatioValue = Double.valueOf(String.valueOf(tempItem.get(CommonConstants.CPU_RATIO)));
int tempTotalThreadValue = Integer.valueOf(String.valueOf(tempItem.get(CommonConstants.TOTAL_THREAD)));
double tempTotalValue = tempMemRatioValue + tempCpuRatioValue + tempTotalThreadValue;
if (tempTotalValue < minTotalValue) {
minMemRatioValue = tempMemRatioValue;
minCpuRatioValue = tempCpuRatioValue;
minTotalThreadValue = tempTotalThreadValue;
minTotalValue = minMemRatioValue + minCpuRatioValue + minTotalThreadValue;
minMemRatioIndex = i;
}
}
if (minMemRatioValue > CommonConstants.MAX_MEM_RATIO || minCpuRatioValue > CommonConstants.MAX_CPU_RATIO) {
logger.error("ClientNodes-->>hashClient4SBySystemCapacity(" + jobClass + ") " +
"the memRatio(" + minMemRatioValue + ") over max mem ratio(" + CommonConstants.MAX_MEM_RATIO + ")" +
"or the cpuRatio("+minCpuRatioValue+") over max cpu ration ("+CommonConstants.MAX_CPU_RATIO+") ");
map.put(CommonConstants.SUCCESS, false);
map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_102);
map.put(CommonConstants.MEM_RATIO, minMemRatioValue);
map.put(CommonConstants.CPU_RATIO, minCpuRatioValue);
return map;
} else {
map.put(CommonConstants.SUCCESS, true);
map.put(CommonConstants.CLIENT_JOB_INFO, items.get(minMemRatioIndex));
return map;
}
}
map.put(CommonConstants.SUCCESS, false);
map.put(CommonConstants.ERROR_CODE, CommonConstants.ERROR_CODE_103);
return map;
}
public boolean containsKey(String id) {
return this.recordsById.containsKey(id);
}
public BasicDBList getRecordsByJobClass(String jobClass) {
return this.recordsByJobClass.get(jobClass);
}
public BasicDBList findRecordsByIP(String ip) {
BasicDBList basicDBList = new BasicDBList();
for (int i = 0; i < this.records.size(); i++) {
BasicDBObject oServer = (BasicDBObject) this.records.get(i);
if (oServer.getString(CommonConstants.IP).equalsIgnoreCase(ip)) {
basicDBList.add(oServer);
}
}
return basicDBList;
}
public synchronized void add(BasicDBObject record) {
String id = record.getString(CommonConstants.ID);
int index = findIndexById(id, this.records);
if (index == -1)
this.records.add(record);
else {
this.records.set(index, record);
}
this.recordsById.put(id, record);
if (!record.containsField(CommonConstants.JOB_CLASS)) {
return;
}
BasicDBList jobClassList = (BasicDBList) record.get(CommonConstants.JOB_CLASS);
for (int i = 0; (jobClassList != null) && (i < jobClassList.size()); i++) {
String tempJobClass = jobClassList.get(i).toString();
this.jobClassSet.add(tempJobClass);
BasicDBList items = this.recordsByJobClass.get(tempJobClass);
if (items == null) {
items = new BasicDBList();
this.recordsByJobClass.put(tempJobClass, items);
}
index = findIndexById(id, items);
if (index == -1)
items.add(record);
else {
items.set(index, record);
}
}
}
public synchronized boolean remove(String id) {
this.recordsById.remove(id);
int index = findIndexById(id, this.records);
boolean flag = index != -1;
if (flag) {
this.records.remove(index);
}
for (Iterator i = this.recordsByJobClass.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
BasicDBList items = (BasicDBList) entry.getValue();
index = findIndexById(id, items);
if (index != -1) {
items.remove(index);
}
if (items.size() == 0) {
this.jobClassSet.remove(entry.getKey());
}
}
return flag;
}
public void clear() {
this.recordsById.clear();
this.recordsByJobClass.clear();
this.records.clear();
this.jobClassSet.clear();
}
}