DaanHoogland commented on code in PR #12014:
URL: https://github.com/apache/cloudstack/pull/12014#discussion_r2509206232
##########
server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java:
##########
@@ -357,10 +372,90 @@ List<Ternary<VirtualMachine, Host, Host>>
getDrsPlan(Cluster cluster,
serviceOfferingDao.findByIdIncludingRemoved(vm.getId(),
vm.getServiceOfferingId()));
}
+ // PHASE 1: Pre-compute suitable hosts (once per eligible VM - never
changes)
+ // Use listHostsForMigrationOfVM to get hosts validated by
getCapableSuitableHosts
+ // This ensures DRS uses the same validation as "find host for
migration" command
Review Comment:
new method with this as javadoc;
```suggestion
/*
* PHASE 1: Pre-compute suitable hosts (once per eligible VM - never
changes)
* Use listHostsForMigrationOfVM to get hosts validated by
getCapableSuitableHosts
* This ensures DRS uses the same validation as "find host for
migration” command
*/
```
##########
server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java:
##########
@@ -438,32 +537,104 @@ Pair<VirtualMachine, Host> getBestMigration(Cluster
cluster, ClusterDrsAlgorithm
List<VirtualMachine> vmList,
Map<Long, ServiceOffering> vmIdServiceOfferingMap,
Map<Long, Ternary<Long, Long, Long>> hostCpuCapacityMap,
- Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap) throws
ConfigurationException {
+ Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap,
+ Map<Long, List<? extends Host>> vmToCompatibleHostsCache,
+ Map<Long, Map<Host, Boolean>> vmToStorageMotionCache,
+ Map<Long, ExcludeList> vmToExcludesMap) throws
ConfigurationException {
+ // Pre-calculate cluster imbalance once per iteration (same for all
VM-host combinations)
+ Double preImbalance = getClusterImbalance(cluster.getId(),
+ new ArrayList<>(hostCpuCapacityMap.values()),
+ new ArrayList<>(hostMemoryCapacityMap.values()),
+ null);
+
+ // Pre-calculate base metrics array once per iteration for optimized
imbalance calculation
+ // This reduces complexity from O(V × H × H) to O(V × H) per iteration
+ String metricType = getClusterDrsMetric(cluster.getId());
+ Map<Long, Ternary<Long, Long, Long>> baseMetricsMap =
"cpu".equals(metricType) ? hostCpuCapacityMap : hostMemoryCapacityMap;
+ double[] baseMetricsArray = new double[baseMetricsMap.size()];
+ Map<Long, Integer> hostIdToIndexMap = new HashMap<>();
+
+ int index = 0;
+ for (Map.Entry<Long, Ternary<Long, Long, Long>> entry :
baseMetricsMap.entrySet()) {
+ Long hostId = entry.getKey();
+ Ternary<Long, Long, Long> metrics = entry.getValue();
+ long used = metrics.first();
+ long actualTotal = metrics.third() - metrics.second();
+ long free = actualTotal - metrics.first();
+ Double metricValue = getMetricValue(cluster.getId(), used, free,
actualTotal, null);
+ if (metricValue != null) {
+ baseMetricsArray[index] = metricValue;
+ hostIdToIndexMap.put(hostId, index);
+ index++;
+ }
+ }
+
+ // Trim array if some values were null
+ if (index < baseMetricsArray.length) {
+ double[] trimmed = new double[index];
+ System.arraycopy(baseMetricsArray, 0, trimmed, 0, index);
+ baseMetricsArray = trimmed;
+ }
+
double improvement = 0;
Pair<VirtualMachine, Host> bestMigration = new Pair<>(null, null);
for (VirtualMachine vm : vmList) {
if (vm.getType().isUsedBySystem() || vm.getState() !=
VirtualMachine.State.Running ||
(MapUtils.isNotEmpty(vm.getDetails()) &&
-
vm.getDetails().get(VmDetailConstants.SKIP_DRS).equalsIgnoreCase("true"))
+
"true".equalsIgnoreCase(vm.getDetails().get(VmDetailConstants.SKIP_DRS)))
) {
continue;
}
- Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>,
Map<Host, Boolean>> hostsForMigrationOfVM = managementServer
- .listHostsForMigrationOfVM(
- vm, 0L, 500L, null, vmList);
- List<? extends Host> compatibleDestinationHosts =
hostsForMigrationOfVM.first().first();
- List<? extends Host> suitableDestinationHosts =
hostsForMigrationOfVM.second();
- Map<Host, Boolean> requiresStorageMotion =
hostsForMigrationOfVM.third();
+ // Use cached compatible hosts
+ List<? extends Host> compatibleHosts =
vmToCompatibleHostsCache.get(vm.getId());
+ Map<Host, Boolean> requiresStorageMotion =
vmToStorageMotionCache.get(vm.getId());
+ ExcludeList excludes = vmToExcludesMap.get(vm.getId());
+
+ if (CollectionUtils.isEmpty(compatibleHosts)) {
+ continue;
+ }
+
+ ServiceOffering serviceOffering =
vmIdServiceOfferingMap.get(vm.getId());
+ if (serviceOffering == null) {
+ continue;
+ }
- for (Host destHost : compatibleDestinationHosts) {
- if (!suitableDestinationHosts.contains(destHost) ||
cluster.getId() != destHost.getClusterId()) {
+ // Pre-calculate VM resource requirements for quick capacity
filtering
Review Comment:
`PreCalculateVMsResourceRequirementsForQuickCapacityFiltering()`
##########
server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java:
##########
@@ -438,32 +537,104 @@ Pair<VirtualMachine, Host> getBestMigration(Cluster
cluster, ClusterDrsAlgorithm
List<VirtualMachine> vmList,
Map<Long, ServiceOffering> vmIdServiceOfferingMap,
Map<Long, Ternary<Long, Long, Long>> hostCpuCapacityMap,
- Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap) throws
ConfigurationException {
+ Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap,
+ Map<Long, List<? extends Host>> vmToCompatibleHostsCache,
+ Map<Long, Map<Host, Boolean>> vmToStorageMotionCache,
+ Map<Long, ExcludeList> vmToExcludesMap) throws
ConfigurationException {
+ // Pre-calculate cluster imbalance once per iteration (same for all
VM-host combinations)
+ Double preImbalance = getClusterImbalance(cluster.getId(),
+ new ArrayList<>(hostCpuCapacityMap.values()),
+ new ArrayList<>(hostMemoryCapacityMap.values()),
+ null);
+
+ // Pre-calculate base metrics array once per iteration for optimized
imbalance calculation
+ // This reduces complexity from O(V × H × H) to O(V × H) per iteration
+ String metricType = getClusterDrsMetric(cluster.getId());
+ Map<Long, Ternary<Long, Long, Long>> baseMetricsMap =
"cpu".equals(metricType) ? hostCpuCapacityMap : hostMemoryCapacityMap;
+ double[] baseMetricsArray = new double[baseMetricsMap.size()];
+ Map<Long, Integer> hostIdToIndexMap = new HashMap<>();
+
+ int index = 0;
+ for (Map.Entry<Long, Ternary<Long, Long, Long>> entry :
baseMetricsMap.entrySet()) {
+ Long hostId = entry.getKey();
+ Ternary<Long, Long, Long> metrics = entry.getValue();
+ long used = metrics.first();
+ long actualTotal = metrics.third() - metrics.second();
+ long free = actualTotal - metrics.first();
+ Double metricValue = getMetricValue(cluster.getId(), used, free,
actualTotal, null);
+ if (metricValue != null) {
+ baseMetricsArray[index] = metricValue;
+ hostIdToIndexMap.put(hostId, index);
+ index++;
+ }
+ }
+
+ // Trim array if some values were null
+ if (index < baseMetricsArray.length) {
+ double[] trimmed = new double[index];
+ System.arraycopy(baseMetricsArray, 0, trimmed, 0, index);
+ baseMetricsArray = trimmed;
+ }
+
double improvement = 0;
Pair<VirtualMachine, Host> bestMigration = new Pair<>(null, null);
for (VirtualMachine vm : vmList) {
if (vm.getType().isUsedBySystem() || vm.getState() !=
VirtualMachine.State.Running ||
(MapUtils.isNotEmpty(vm.getDetails()) &&
-
vm.getDetails().get(VmDetailConstants.SKIP_DRS).equalsIgnoreCase("true"))
+
"true".equalsIgnoreCase(vm.getDetails().get(VmDetailConstants.SKIP_DRS)))
) {
continue;
}
- Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>,
Map<Host, Boolean>> hostsForMigrationOfVM = managementServer
- .listHostsForMigrationOfVM(
- vm, 0L, 500L, null, vmList);
- List<? extends Host> compatibleDestinationHosts =
hostsForMigrationOfVM.first().first();
- List<? extends Host> suitableDestinationHosts =
hostsForMigrationOfVM.second();
- Map<Host, Boolean> requiresStorageMotion =
hostsForMigrationOfVM.third();
+ // Use cached compatible hosts
+ List<? extends Host> compatibleHosts =
vmToCompatibleHostsCache.get(vm.getId());
+ Map<Host, Boolean> requiresStorageMotion =
vmToStorageMotionCache.get(vm.getId());
+ ExcludeList excludes = vmToExcludesMap.get(vm.getId());
+
+ if (CollectionUtils.isEmpty(compatibleHosts)) {
+ continue;
+ }
+
+ ServiceOffering serviceOffering =
vmIdServiceOfferingMap.get(vm.getId());
+ if (serviceOffering == null) {
+ continue;
+ }
- for (Host destHost : compatibleDestinationHosts) {
- if (!suitableDestinationHosts.contains(destHost) ||
cluster.getId() != destHost.getClusterId()) {
+ // Pre-calculate VM resource requirements for quick capacity
filtering
+ long vmCpu = (long) serviceOffering.getCpu() *
serviceOffering.getSpeed();
+ long vmMemory = serviceOffering.getRamSize() * 1024L * 1024L;
+
+ for (Host destHost : compatibleHosts) {
+ if (cluster.getId() != destHost.getClusterId()) {
continue;
}
+
+ // Check affinity constraints
+ if (excludes != null && excludes.shouldAvoid(destHost)) {
+ continue;
+ }
+
+ // Quick capacity pre-filter: skip hosts that don't have
enough capacity
Review Comment:
`SkipHostsThatHaveNoCapacity()`
##########
server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java:
##########
@@ -438,32 +537,104 @@ Pair<VirtualMachine, Host> getBestMigration(Cluster
cluster, ClusterDrsAlgorithm
List<VirtualMachine> vmList,
Map<Long, ServiceOffering> vmIdServiceOfferingMap,
Map<Long, Ternary<Long, Long, Long>> hostCpuCapacityMap,
- Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap) throws
ConfigurationException {
+ Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap,
+ Map<Long, List<? extends Host>> vmToCompatibleHostsCache,
+ Map<Long, Map<Host, Boolean>> vmToStorageMotionCache,
+ Map<Long, ExcludeList> vmToExcludesMap) throws
ConfigurationException {
+ // Pre-calculate cluster imbalance once per iteration (same for all
VM-host combinations)
+ Double preImbalance = getClusterImbalance(cluster.getId(),
+ new ArrayList<>(hostCpuCapacityMap.values()),
+ new ArrayList<>(hostMemoryCapacityMap.values()),
+ null);
+
+ // Pre-calculate base metrics array once per iteration for optimized
imbalance calculation
+ // This reduces complexity from O(V × H × H) to O(V × H) per iteration
+ String metricType = getClusterDrsMetric(cluster.getId());
+ Map<Long, Ternary<Long, Long, Long>> baseMetricsMap =
"cpu".equals(metricType) ? hostCpuCapacityMap : hostMemoryCapacityMap;
+ double[] baseMetricsArray = new double[baseMetricsMap.size()];
+ Map<Long, Integer> hostIdToIndexMap = new HashMap<>();
+
+ int index = 0;
+ for (Map.Entry<Long, Ternary<Long, Long, Long>> entry :
baseMetricsMap.entrySet()) {
+ Long hostId = entry.getKey();
+ Ternary<Long, Long, Long> metrics = entry.getValue();
+ long used = metrics.first();
+ long actualTotal = metrics.third() - metrics.second();
+ long free = actualTotal - metrics.first();
+ Double metricValue = getMetricValue(cluster.getId(), used, free,
actualTotal, null);
+ if (metricValue != null) {
+ baseMetricsArray[index] = metricValue;
+ hostIdToIndexMap.put(hostId, index);
+ index++;
+ }
+ }
+
+ // Trim array if some values were null
+ if (index < baseMetricsArray.length) {
+ double[] trimmed = new double[index];
+ System.arraycopy(baseMetricsArray, 0, trimmed, 0, index);
+ baseMetricsArray = trimmed;
+ }
+
double improvement = 0;
Pair<VirtualMachine, Host> bestMigration = new Pair<>(null, null);
for (VirtualMachine vm : vmList) {
if (vm.getType().isUsedBySystem() || vm.getState() !=
VirtualMachine.State.Running ||
(MapUtils.isNotEmpty(vm.getDetails()) &&
-
vm.getDetails().get(VmDetailConstants.SKIP_DRS).equalsIgnoreCase("true"))
+
"true".equalsIgnoreCase(vm.getDetails().get(VmDetailConstants.SKIP_DRS)))
) {
continue;
}
- Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>,
Map<Host, Boolean>> hostsForMigrationOfVM = managementServer
- .listHostsForMigrationOfVM(
- vm, 0L, 500L, null, vmList);
- List<? extends Host> compatibleDestinationHosts =
hostsForMigrationOfVM.first().first();
- List<? extends Host> suitableDestinationHosts =
hostsForMigrationOfVM.second();
- Map<Host, Boolean> requiresStorageMotion =
hostsForMigrationOfVM.third();
+ // Use cached compatible hosts
+ List<? extends Host> compatibleHosts =
vmToCompatibleHostsCache.get(vm.getId());
+ Map<Host, Boolean> requiresStorageMotion =
vmToStorageMotionCache.get(vm.getId());
+ ExcludeList excludes = vmToExcludesMap.get(vm.getId());
+
+ if (CollectionUtils.isEmpty(compatibleHosts)) {
+ continue;
+ }
+
+ ServiceOffering serviceOffering =
vmIdServiceOfferingMap.get(vm.getId());
+ if (serviceOffering == null) {
+ continue;
+ }
- for (Host destHost : compatibleDestinationHosts) {
- if (!suitableDestinationHosts.contains(destHost) ||
cluster.getId() != destHost.getClusterId()) {
+ // Pre-calculate VM resource requirements for quick capacity
filtering
+ long vmCpu = (long) serviceOffering.getCpu() *
serviceOffering.getSpeed();
+ long vmMemory = serviceOffering.getRamSize() * 1024L * 1024L;
+
+ for (Host destHost : compatibleHosts) {
+ if (cluster.getId() != destHost.getClusterId()) {
continue;
}
+
+ // Check affinity constraints
Review Comment:
`CheckAffinityConstraints()`
##########
server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java:
##########
@@ -357,10 +372,90 @@ List<Ternary<VirtualMachine, Host, Host>>
getDrsPlan(Cluster cluster,
serviceOfferingDao.findByIdIncludingRemoved(vm.getId(),
vm.getServiceOfferingId()));
}
+ // PHASE 1: Pre-compute suitable hosts (once per eligible VM - never
changes)
+ // Use listHostsForMigrationOfVM to get hosts validated by
getCapableSuitableHosts
+ // This ensures DRS uses the same validation as "find host for
migration" command
+ Map<Long, List<? extends Host>> vmToCompatibleHostsCache = new
HashMap<>();
+ Map<Long, Map<Host, Boolean>> vmToStorageMotionCache = new HashMap<>();
+
+ for (VirtualMachine vm : vmList) {
+ // Skip ineligible VMs
+ if (vm.getType().isUsedBySystem() ||
+ vm.getState() != VirtualMachine.State.Running ||
+ (MapUtils.isNotEmpty(vm.getDetails()) &&
+
"true".equalsIgnoreCase(vm.getDetails().get(VmDetailConstants.SKIP_DRS)))) {
+ continue;
+ }
+
+ try {
+ // Use listHostsForMigrationOfVM to get suitable hosts
(validated by getCapableSuitableHosts)
+ // This ensures the same validation as the "find host for
migration" command
+ Ternary<Pair<List<? extends Host>, Integer>, List<? extends
Host>, Map<Host, Boolean>> hostsForMigration =
+ managementServer.listHostsForMigrationOfVM(vm, 0L, 500L,
null, vmList);
+
+ List<? extends Host> suitableHosts =
hostsForMigration.second(); // Get suitable hosts (validated by HostAllocator)
+ Map<Host, Boolean> requiresStorageMotion =
hostsForMigration.third();
+
+ if (suitableHosts != null && !suitableHosts.isEmpty()) {
+ vmToCompatibleHostsCache.put(vm.getId(), suitableHosts);
+ vmToStorageMotionCache.put(vm.getId(),
requiresStorageMotion);
+ }
+ } catch (Exception e) {
+ logger.debug("Could not get suitable hosts for VM {}: {}", vm,
e.getMessage());
+ }
+ }
+
+ // Pre-fetch affinity group mappings for all eligible VMs (once,
before iterations)
+ // This allows us to skip expensive affinity processing for VMs
without affinity groups
+ Set<Long> vmsWithAffinityGroups = new HashSet<>();
+ for (VirtualMachine vm : vmList) {
+ if (vmToCompatibleHostsCache.containsKey(vm.getId())) {
+ // Check if VM has any affinity groups - if list is empty, VM
has no affinity groups
+ List<AffinityGroupVMMapVO> affinityGroupMappings =
affinityGroupVMMapDao.listByInstanceId(vm.getId());
+ if (CollectionUtils.isNotEmpty(affinityGroupMappings)) {
+ vmsWithAffinityGroups.add(vm.getId());
+ }
+ }
+ }
+
+ // PHASE 2: Iteration loop with affinity check per iteration
Review Comment:
`phase2Method()`.
##########
server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java:
##########
@@ -438,32 +537,104 @@ Pair<VirtualMachine, Host> getBestMigration(Cluster
cluster, ClusterDrsAlgorithm
List<VirtualMachine> vmList,
Map<Long, ServiceOffering> vmIdServiceOfferingMap,
Map<Long, Ternary<Long, Long, Long>> hostCpuCapacityMap,
- Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap) throws
ConfigurationException {
+ Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap,
+ Map<Long, List<? extends Host>> vmToCompatibleHostsCache,
+ Map<Long, Map<Host, Boolean>> vmToStorageMotionCache,
+ Map<Long, ExcludeList> vmToExcludesMap) throws
ConfigurationException {
+ // Pre-calculate cluster imbalance once per iteration (same for all
VM-host combinations)
+ Double preImbalance = getClusterImbalance(cluster.getId(),
+ new ArrayList<>(hostCpuCapacityMap.values()),
+ new ArrayList<>(hostMemoryCapacityMap.values()),
+ null);
+
+ // Pre-calculate base metrics array once per iteration for optimized
imbalance calculation
+ // This reduces complexity from O(V × H × H) to O(V × H) per iteration
+ String metricType = getClusterDrsMetric(cluster.getId());
+ Map<Long, Ternary<Long, Long, Long>> baseMetricsMap =
"cpu".equals(metricType) ? hostCpuCapacityMap : hostMemoryCapacityMap;
+ double[] baseMetricsArray = new double[baseMetricsMap.size()];
+ Map<Long, Integer> hostIdToIndexMap = new HashMap<>();
+
+ int index = 0;
+ for (Map.Entry<Long, Ternary<Long, Long, Long>> entry :
baseMetricsMap.entrySet()) {
+ Long hostId = entry.getKey();
+ Ternary<Long, Long, Long> metrics = entry.getValue();
+ long used = metrics.first();
+ long actualTotal = metrics.third() - metrics.second();
+ long free = actualTotal - metrics.first();
+ Double metricValue = getMetricValue(cluster.getId(), used, free,
actualTotal, null);
+ if (metricValue != null) {
+ baseMetricsArray[index] = metricValue;
+ hostIdToIndexMap.put(hostId, index);
+ index++;
+ }
+ }
+
+ // Trim array if some values were null
+ if (index < baseMetricsArray.length) {
+ double[] trimmed = new double[index];
+ System.arraycopy(baseMetricsArray, 0, trimmed, 0, index);
+ baseMetricsArray = trimmed;
+ }
+
double improvement = 0;
Pair<VirtualMachine, Host> bestMigration = new Pair<>(null, null);
for (VirtualMachine vm : vmList) {
if (vm.getType().isUsedBySystem() || vm.getState() !=
VirtualMachine.State.Running ||
(MapUtils.isNotEmpty(vm.getDetails()) &&
-
vm.getDetails().get(VmDetailConstants.SKIP_DRS).equalsIgnoreCase("true"))
+
"true".equalsIgnoreCase(vm.getDetails().get(VmDetailConstants.SKIP_DRS)))
) {
continue;
}
- Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>,
Map<Host, Boolean>> hostsForMigrationOfVM = managementServer
- .listHostsForMigrationOfVM(
- vm, 0L, 500L, null, vmList);
- List<? extends Host> compatibleDestinationHosts =
hostsForMigrationOfVM.first().first();
- List<? extends Host> suitableDestinationHosts =
hostsForMigrationOfVM.second();
- Map<Host, Boolean> requiresStorageMotion =
hostsForMigrationOfVM.third();
+ // Use cached compatible hosts
Review Comment:
`UseCachedCompatibleHosts()`
##########
server/src/main/java/org/apache/cloudstack/cluster/ClusterDrsServiceImpl.java:
##########
@@ -438,32 +537,104 @@ Pair<VirtualMachine, Host> getBestMigration(Cluster
cluster, ClusterDrsAlgorithm
List<VirtualMachine> vmList,
Map<Long, ServiceOffering> vmIdServiceOfferingMap,
Map<Long, Ternary<Long, Long, Long>> hostCpuCapacityMap,
- Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap) throws
ConfigurationException {
+ Map<Long, Ternary<Long, Long, Long>> hostMemoryCapacityMap,
+ Map<Long, List<? extends Host>> vmToCompatibleHostsCache,
+ Map<Long, Map<Host, Boolean>> vmToStorageMotionCache,
+ Map<Long, ExcludeList> vmToExcludesMap) throws
ConfigurationException {
+ // Pre-calculate cluster imbalance once per iteration (same for all
VM-host combinations)
+ Double preImbalance = getClusterImbalance(cluster.getId(),
+ new ArrayList<>(hostCpuCapacityMap.values()),
+ new ArrayList<>(hostMemoryCapacityMap.values()),
+ null);
+
+ // Pre-calculate base metrics array once per iteration for optimized
imbalance calculation
+ // This reduces complexity from O(V × H × H) to O(V × H) per iteration
+ String metricType = getClusterDrsMetric(cluster.getId());
+ Map<Long, Ternary<Long, Long, Long>> baseMetricsMap =
"cpu".equals(metricType) ? hostCpuCapacityMap : hostMemoryCapacityMap;
+ double[] baseMetricsArray = new double[baseMetricsMap.size()];
+ Map<Long, Integer> hostIdToIndexMap = new HashMap<>();
+
+ int index = 0;
+ for (Map.Entry<Long, Ternary<Long, Long, Long>> entry :
baseMetricsMap.entrySet()) {
+ Long hostId = entry.getKey();
+ Ternary<Long, Long, Long> metrics = entry.getValue();
+ long used = metrics.first();
+ long actualTotal = metrics.third() - metrics.second();
+ long free = actualTotal - metrics.first();
+ Double metricValue = getMetricValue(cluster.getId(), used, free,
actualTotal, null);
+ if (metricValue != null) {
+ baseMetricsArray[index] = metricValue;
+ hostIdToIndexMap.put(hostId, index);
+ index++;
+ }
+ }
+
+ // Trim array if some values were null
+ if (index < baseMetricsArray.length) {
+ double[] trimmed = new double[index];
+ System.arraycopy(baseMetricsArray, 0, trimmed, 0, index);
+ baseMetricsArray = trimmed;
+ }
+
double improvement = 0;
Pair<VirtualMachine, Host> bestMigration = new Pair<>(null, null);
for (VirtualMachine vm : vmList) {
if (vm.getType().isUsedBySystem() || vm.getState() !=
VirtualMachine.State.Running ||
(MapUtils.isNotEmpty(vm.getDetails()) &&
-
vm.getDetails().get(VmDetailConstants.SKIP_DRS).equalsIgnoreCase("true"))
+
"true".equalsIgnoreCase(vm.getDetails().get(VmDetailConstants.SKIP_DRS)))
) {
continue;
}
- Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>,
Map<Host, Boolean>> hostsForMigrationOfVM = managementServer
- .listHostsForMigrationOfVM(
- vm, 0L, 500L, null, vmList);
- List<? extends Host> compatibleDestinationHosts =
hostsForMigrationOfVM.first().first();
- List<? extends Host> suitableDestinationHosts =
hostsForMigrationOfVM.second();
- Map<Host, Boolean> requiresStorageMotion =
hostsForMigrationOfVM.third();
+ // Use cached compatible hosts
+ List<? extends Host> compatibleHosts =
vmToCompatibleHostsCache.get(vm.getId());
+ Map<Host, Boolean> requiresStorageMotion =
vmToStorageMotionCache.get(vm.getId());
+ ExcludeList excludes = vmToExcludesMap.get(vm.getId());
+
+ if (CollectionUtils.isEmpty(compatibleHosts)) {
+ continue;
+ }
+
+ ServiceOffering serviceOffering =
vmIdServiceOfferingMap.get(vm.getId());
+ if (serviceOffering == null) {
+ continue;
+ }
- for (Host destHost : compatibleDestinationHosts) {
- if (!suitableDestinationHosts.contains(destHost) ||
cluster.getId() != destHost.getClusterId()) {
+ // Pre-calculate VM resource requirements for quick capacity
filtering
+ long vmCpu = (long) serviceOffering.getCpu() *
serviceOffering.getSpeed();
+ long vmMemory = serviceOffering.getRamSize() * 1024L * 1024L;
+
+ for (Host destHost : compatibleHosts) {
Review Comment:
this loop deserves its own method as well
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]