package org.ovirt.engine.core.bll;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.ovirt.engine.core.common.businessentities.ServerCpu;
import org.ovirt.engine.core.common.config.Config;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.compat.LogCompat;
import org.ovirt.engine.core.compat.LogFactoryCompat;
import org.ovirt.engine.core.compat.StringHelper;
import org.ovirt.engine.core.compat.Version;
public final class CpuFlagsManagerHandler {
private static java.util.HashMap<Version, CpuFlagsManager> _managersDictionary =
new java.util.HashMap<Version, CpuFlagsManager>();
public static void InitDictionaries() {
_managersDictionary.clear();
for (Version ver : Config.<java.util.HashSet<Version>> GetValue(ConfigValues.SupportedClusterLevels)) {
_managersDictionary.put(ver, new CpuFlagsManager(ver));
}
}
public static String GetVDSVerbDataByCpuName(String name, Version ver) {
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
return cpuFlagsManager.GetVDSVerbDataByCpuName(name);
}
return null;
}
public static java.util.ArrayList<ServerCpu> AllServerCpuList(Version ver) {
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
return cpuFlagsManager.getAllServerCpuList();
}
return new java.util.ArrayList<ServerCpu>();
}
public static ServerCpu FindMaxServerCpu(String clusterCpuName, String serverFlags, Version ver) {
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
return cpuFlagsManager.FindMaxServerCpu(clusterCpuName, serverFlags);
}
return null;
}
/**
* Returns missing CPU flags if any, or null if the server match the cluster
* CPU flags
*
* @param clusterCpuName
* @param serverFlags
* @param ver
* @return list of missing CPU flags
*/
public static List<String> missingServerCpuFlags(String clusterCpuName, String serverFlags, Version ver) {
List<String> list = null;
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
list = cpuFlagsManager.missingServerCpuFlags(clusterCpuName, serverFlags);
}
return list;
}
public static boolean CheckIfServerAndClusterCanFit(String clusterCpuName, String serverFlags, Version ver) {
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
return cpuFlagsManager.CheckIfServerAndClusterCanFit(clusterCpuName, serverFlags);
}
return false;
}
public static boolean CheckIfCpusSameManufacture(String cpuName1, String cpuName2, Version ver) {
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
return cpuFlagsManager.CheckIfCpusSameManufacture(cpuName1, cpuName2);
}
return false;
}
public static boolean CheckIfCpusExist(String cpuName, Version ver) {
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
return cpuFlagsManager.CheckIfCpusExist(cpuName);
}
return false;
}
/**
* Returns all CPU lower than the given CPU INCLUDING IT !!!
*
* @param cpuName
* @return
*/
public static List<ServerCpu> GetAllServerCpusBelowCpu(String cpuName, Version ver) {
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
return cpuFlagsManager.GetAllServerCpusBelowCpu(cpuName);
}
return new java.util.ArrayList<ServerCpu>();
}
/**
* Finds max server cpu by server cpu flags only
*
* @param flags
* @return
*/
public static ServerCpu FindMaxServerCpuByFlags(String flags, Version ver) {
CpuFlagsManager cpuFlagsManager = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
return cpuFlagsManager.FindMaxServerCpuByFlags(flags);
}
return null;
}
private static class CpuFlagsManager {
private java.util.ArrayList<ServerCpu> _intelCpuList;
private java.util.ArrayList<ServerCpu> _amdCpuList;
private java.util.ArrayList<ServerCpu> _allCpuList = new java.util.ArrayList<ServerCpu>();
private java.util.HashMap<String, ServerCpu> _intelCpuByNameDictionary =
new java.util.HashMap<String, ServerCpu>();
private java.util.HashMap<String, ServerCpu> _amdCpuByNameDictionary =
new java.util.HashMap<String, ServerCpu>();
private final String _intelFlag = "vmx";
public CpuFlagsManager(Version ver) {
InitDictionaries(ver);
}
public ServerCpu getServerCpuByName(String cpuName) {
ServerCpu result = null;
if (cpuName != null) {
result = _intelCpuByNameDictionary.get(cpuName);
if (result == null) {
result = _amdCpuByNameDictionary.get(cpuName);
}
}
return result;
}
public void InitDictionaries(Version ver) {
// init dictionaries
_intelCpuByNameDictionary.clear();
_amdCpuByNameDictionary.clear();
_allCpuList.clear();
String[] cpus = Config.<String> GetValue(ConfigValues.ServerCPUList, ver.toString()).split("[;]", -1);
String[] info;
for (String cpu : cpus) {
if (!StringHelper.isNullOrEmpty(cpu)) {
// [0]-level, [1]-name, [2]-flags, [3]-verb
info = cpu.split("[:]", -1);
if (info.length == 4) {
// if no flags at all create new list instead of split
java.util.HashSet<String> flgs =
(StringHelper.isNullOrEmpty(info[2])) ? new java.util.HashSet<String>()
: new java.util.HashSet<String>(java.util.Arrays.asList(info[2].split("[,]", -1)));
ServerCpu sc = new ServerCpu(info[1], Integer.parseInt(info[0].trim()), flgs, info[3]);
if (sc.getFlags().contains(_intelFlag)) {
_intelCpuByNameDictionary.put(sc.getCpuName(), sc);
} else {
_amdCpuByNameDictionary.put(sc.getCpuName(), sc);
}
_allCpuList.add(sc);
} else {
log.errorFormat("Error getting info for CPU: {0}, not in expected format.", cpu);
}
}
}
// LINQ FIXED 29456
// _intelCpuList = _intelCpuByNameDictionary.Select(a =>
// a.Value).OrderBy(a => a.Level).ToList<ServerCpu>();
// _amdCpuList = _amdCpuByNameDictionary.Select(a =>
// a.Value).OrderBy(a => a.Level).ToList<ServerCpu>();
_intelCpuList = new ArrayList<ServerCpu>(_intelCpuByNameDictionary.values());
_amdCpuList = new ArrayList<ServerCpu>(_amdCpuByNameDictionary.values());
Comparator<ServerCpu> cpuComparator = new Comparator<ServerCpu>() {
@Override
public int compare(ServerCpu o1, ServerCpu o2) {
return Integer.valueOf(o1.getLevel()).compareTo(o2.getLevel());
}
};
// Sort by the highest cpu level so the highest cpu match will be
// selected first
Collections.sort(_intelCpuList, cpuComparator);
Collections.sort(_amdCpuList, cpuComparator);
}
private static boolean CheckIfListIsValid(java.util.ArrayList<ServerCpu> list) {
boolean result = true;
for (int i = 1; i < list.size(); i++) {
// check that list[i].Flags contains all list[i-1].Flags and
// larger (have more members).
// LINQ FIXED 29456
// if (!(list[i].Flags.Intersect(list[i - 1].Flags).Count() ==
// list[i - 1].Flags.Count &&
// list[i].Flags.Count > list[i - 1].Flags.Count))
if (!(CollectionUtils.intersection(list.get(i).getFlags(), list.get(i - 1).getFlags()).size() == list
.get(i - 1).getFlags().size() && list.get(i).getFlags().size() > list.get(i - 1).getFlags()
.size())) {
result = false;
break;
}
}
return result;
}
public String GetVDSVerbDataByCpuName(String name) {
String result = null;
ServerCpu sc = null;
if (name != null) {
if ((sc = _intelCpuByNameDictionary.get(name)) != null
|| (sc = _amdCpuByNameDictionary.get(name)) != null) {
result = sc.getVdsVerbData();
}
}
return result;
}
public java.util.ArrayList<ServerCpu> getAllServerCpuList() {
return _allCpuList;
}
/**
* Finds max server cpu by cluster name and server cpu flags
*
* @param clusterCpuName
* @param serverFlags
* @return
*/
public ServerCpu FindMaxServerCpu(String clusterCpuName, String serverFlags) {
ServerCpu result = null;
ServerCpu clusterCpu = null;
// if there are flags but no cluster or cant find cluster
if (!StringHelper.isNullOrEmpty(serverFlags) && clusterCpuName != null) {
if (!((clusterCpu = _intelCpuByNameDictionary.get(clusterCpuName)) != null)
&& !((clusterCpu = _amdCpuByNameDictionary.get(clusterCpuName)) != null)) {
result = FindMaxServerCpuByFlags(serverFlags);
} else {
java.util.HashSet<String> lstFlags = new java.util.HashSet<String>(
java.util.Arrays.asList(serverFlags.split("[,]", -1)));
// check if to search in intel or amd
result =
(lstFlags.contains(_intelFlag)) ? FindServerCpuByFlags(lstFlags, clusterCpu, _intelCpuList)
: FindServerCpuByFlags(lstFlags, clusterCpu, _amdCpuList);
}
}
return result;
}
private ServerCpu FindServerCpuByFlags(java.util.HashSet<String> lstFlags, ServerCpu clusterCpu,
java.util.ArrayList<ServerCpu> fullList) {
ServerCpu result = null;
int i;
// check if server ok with cluster
if (CheckIfFlagsContainsCpuFlags(clusterCpu, lstFlags)) {
// then should look up
for (i = fullList.indexOf(clusterCpu) + 1; i < fullList.size(); i++) {
if (!CheckIfFlagsContainsCpuFlags(fullList.get(i), lstFlags)) {
break;
}
}
result = fullList.get(i - 1);
} else {
// then should look down
for (i = fullList.indexOf(clusterCpu) - 1; i >= 0; i--) {
if (CheckIfFlagsContainsCpuFlags(fullList.get(i), lstFlags)) {
break;
}
}
// If i is lower than 0 then server cpu could not found
if (i >= 0) {
result = fullList.get(i);
}
}
return result;
}
/**
* Returns missing CPU flags if any, or null if the server match the
* cluster CPU flags
*
* @param clusterCpuName
* @param serverFlags
* @return list of missing CPU flags
*/
public List<String> missingServerCpuFlags(String clusterCpuName, String serverFlags) {
ServerCpu clusterCpu = null;
List<String> missingFlags = null;
java.util.HashSet<String> lstServerflags =
(StringHelper.isNullOrEmpty(serverFlags)) ? new java.util.HashSet<String>()
: new java.util.HashSet<String>(java.util.Arrays.asList(serverFlags.split("[,]", -1)));
// first find cluster cpu
if (clusterCpuName != null
&& ((clusterCpu = _intelCpuByNameDictionary.get(clusterCpuName)) != null || (clusterCpu =
_amdCpuByNameDictionary
.get(clusterCpuName)) != null)) {
for (String flag : clusterCpu.getFlags()) {
if (!lstServerflags.contains(flag)) {
if (missingFlags == null) {
missingFlags = new ArrayList<String>();
}
missingFlags.add(flag);
}
}
}
return missingFlags;
}
/**
* Return true if given flag list contains all flags of given ServerCpu
* object's flags.
*
* @param clusterCpu
* @param lstServerflags
* @return
*/
private boolean CheckIfFlagsContainsCpuFlags(ServerCpu clusterCpu, java.util.HashSet<String> lstServerflags) {
// LINQ 29456
// return (clusterCpu.Flags.Intersect(lstServerflags).Count() ==
// clusterCpu.Flags.Count);
return CollectionUtils.intersection(clusterCpu.getFlags(), lstServerflags).size() == clusterCpu.getFlags()
.size();
// LINQ 29456
}
/**
* This method only check if server and cluster have the same cpu (intel
* or amd)
*
* @param clusterCpuName
* @param serverFlags
* @return
*/
public boolean CheckIfServerAndClusterCanFit(String clusterCpuName, String serverFlags) {
if (clusterCpuName == null) {
return false;
} else {
if (StringHelper.isNullOrEmpty(serverFlags)) {
return true;
} else {
java.util.HashSet<String> lstServerflags = new java.util.HashSet<String>(
java.util.Arrays.asList(serverFlags.split("[,]", -1)));
return (lstServerflags.contains(_intelFlag)) ? _intelCpuByNameDictionary
.containsKey(clusterCpuName) : _amdCpuByNameDictionary.containsKey(clusterCpuName);
}
}
}
/**
* This method returns true if the given cpus are from the same
* manufature (intel or amd)
*
* @param cpuName1
* @param cpuName2
* @return
*/
public boolean CheckIfCpusSameManufacture(String cpuName1, String cpuName2) {
boolean result = false;
if (cpuName1 != null && cpuName2 != null) {
result = (_intelCpuByNameDictionary.containsKey(cpuName1)) ? _intelCpuByNameDictionary
.containsKey(cpuName2) : _amdCpuByNameDictionary.containsKey(cpuName2);
}
return result;
}
public boolean CheckIfCpusExist(String cpuName) {
return cpuName != null
&& (_intelCpuByNameDictionary.containsKey(cpuName) || _amdCpuByNameDictionary.containsKey(cpuName));
}
/**
* Returns all CPU lower than the given CPU INCLUDING IT !!!
*
* @param cpuName
* @return
*/
public List<ServerCpu> GetAllServerCpusBelowCpu(String cpuName) {
List<ServerCpu> result = new java.util.ArrayList<ServerCpu>();
if (cpuName != null) {
ServerCpu sc = null;
// find server cpu object
if ((sc = _intelCpuByNameDictionary.get(cpuName)) != null) {
// LINQ 29456
// result = _intelCpuList.Take(_intelCpuList.IndexOf(sc) +
// 1).ToList();
result = _intelCpuList.subList(0, _intelCpuList.indexOf(sc) + 1);
} else if ((sc = _amdCpuByNameDictionary.get(cpuName)) != null) {
// LINQ 29456
// result = _amdCpuList.Take(_amdCpuList.IndexOf(sc) +
// 1).ToList();
result = _amdCpuList.subList(0, _amdCpuList.indexOf(sc) + 1);
}
}
return result;
}
/**
* Finds max server cpu by server cpu flags only
*
* @param flags
* @return
*/
public ServerCpu FindMaxServerCpuByFlags(String flags) {
ServerCpu result = null;
java.util.HashSet<String> lstFlags = (StringHelper.isNullOrEmpty(flags)) ? new java.util.HashSet<String>()
: new java.util.HashSet<String>(java.util.Arrays.asList(flags.split("[,]", -1)));
if (lstFlags.contains(_intelFlag)) {
for (int i = _intelCpuList.size() - 1; i >= 0; i--) {
if (CheckIfFlagsContainsCpuFlags(_intelCpuList.get(i), lstFlags)) {
result = _intelCpuList.get(i);
break;
}
}
} else {
for (int i = _amdCpuList.size() - 1; i >= 0; i--) {
if (CheckIfFlagsContainsCpuFlags(_amdCpuList.get(i), lstFlags)) {
result = _amdCpuList.get(i);
break;
}
}
}
return result;
}
}
public static int compareCpuLevels(String cpuName1 , String cpuName2,Version ver) {
CpuFlagsManager cpuFlagsManager = null;
ServerCpu server1 = null;
ServerCpu server2 = null;
if ((cpuFlagsManager = _managersDictionary.get(ver)) != null) {
server1 = cpuFlagsManager.getServerCpuByName(cpuName1);
server2 = cpuFlagsManager.getServerCpuByName(cpuName2);
}
int server1Level = (server1 != null)?server1.getLevel():0;
int server2Level = (server2 != null)?server2.getLevel():0;
return server1Level - server2Level;
}
private static LogCompat log = LogFactoryCompat.getLog(CpuFlagsManagerHandler.class);
}