This is an automated email from the ASF dual-hosted git repository.

DaanHoogland pushed a commit to branch 4.22
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.22 by this push:
     new 4625a436722 Batch NIC and VLAN reads in collectVmNetworkStatistics to 
reduce per-NIC DB round-trips (#13474)
4625a436722 is described below

commit 4625a43672204a6a7b7d9fe0ba8d21ff21df91e7
Author: Vishesh <[email protected]>
AuthorDate: Mon Jun 29 19:15:56 2026 +0530

    Batch NIC and VLAN reads in collectVmNetworkStatistics to reduce per-NIC DB 
round-trips (#13474)
    
    Co-authored-by: Aaron Chung <[email protected]>
---
 .../src/main/java/com/cloud/dc/dao/VlanDao.java    |  2 ++
 .../main/java/com/cloud/dc/dao/VlanDaoImpl.java    | 14 ++++++++++-
 .../src/main/java/com/cloud/vm/dao/NicDao.java     |  2 ++
 .../src/main/java/com/cloud/vm/dao/NicDaoImpl.java | 15 ++++++++++--
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  | 28 ++++++++++++++++++----
 5 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java 
b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
index a6c267bb189..beab7ce2cd5 100644
--- a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
+++ b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
@@ -51,6 +51,8 @@ public interface VlanDao extends GenericDao<VlanVO, Long> {
 
     List<VlanVO> listVlansByNetworkId(long networkId);
 
+    List<VlanVO> listVlansByNetworkIds(List<Long> networkIds);
+
     List<VlanVO> listVlansByNetworkIdIncludingRemoved(long networkId);
 
     List<VlanVO> listVlansByPhysicalNetworkId(long physicalNetworkId);
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java 
b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
index d9fad3cad12..5687e858877 100644
--- a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
@@ -20,6 +20,7 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -27,6 +28,7 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import com.cloud.dc.VlanDetailsVO;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
@@ -134,7 +136,7 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, 
Long> implements VlanDao
         ZoneTypeSearch.done();
 
         NetworkVlanSearch = createSearchBuilder();
-        NetworkVlanSearch.and("networkId", 
NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
+        NetworkVlanSearch.and("networkId", 
NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.IN);
         NetworkVlanSearch.done();
 
         PhysicalNetworkVlanSearch = createSearchBuilder();
@@ -392,6 +394,16 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, 
Long> implements VlanDao
         return listBy(sc);
     }
 
+    @Override
+    public List<VlanVO> listVlansByNetworkIds(List<Long> networkIds) {
+        if (CollectionUtils.isEmpty(networkIds)) {
+            return Collections.emptyList();
+        }
+        SearchCriteria<VlanVO> sc = NetworkVlanSearch.create();
+        sc.setParameters("networkId", networkIds.toArray());
+        return listBy(sc);
+    }
+
     @Override public List<VlanVO> listVlansByNetworkIdIncludingRemoved(long 
networkId) {
         SearchCriteria<VlanVO> sc = NetworkVlanSearch.create();
         sc.setParameters("networkId", networkId);
diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java 
b/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java
index 96a1b6e3bd1..2718127d648 100644
--- a/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java
@@ -97,6 +97,8 @@ public interface NicDao extends GenericDao<NicVO, Long> {
 
     NicVO findByMacAddress(String macAddress, long networkId);
 
+    List<NicVO> listByMacAddresses(List<String> macAddresses);
+
     NicVO findByNetworkIdAndMacAddressIncludingRemoved(long networkId, String 
mac);
 
     List<NicVO> findNicsByIpv6GatewayIpv6CidrAndReserver(String ipv6Gateway, 
String ipv6Cidr, String reserverName);
diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java 
b/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java
index 78966a09e97..f4f3b0d6ad6 100644
--- a/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java
@@ -18,12 +18,13 @@ package com.cloud.vm.dao;
 
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
-import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.stereotype.Component;
 
 import com.cloud.utils.db.Filter;
@@ -71,7 +72,7 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> 
implements NicDao {
         AllFieldsSearch.and("strategy", 
AllFieldsSearch.entity().getReservationStrategy(), Op.EQ);
         AllFieldsSearch.and("strategyNEQ", 
AllFieldsSearch.entity().getReservationStrategy(), Op.NEQ);
         
AllFieldsSearch.and("reserverName",AllFieldsSearch.entity().getReserver(),Op.EQ);
-        AllFieldsSearch.and("macAddress", 
AllFieldsSearch.entity().getMacAddress(), Op.EQ);
+        AllFieldsSearch.and("macAddress", 
AllFieldsSearch.entity().getMacAddress(), Op.IN);
         AllFieldsSearch.and("deviceid", 
AllFieldsSearch.entity().getDeviceId(), Op.EQ);
         AllFieldsSearch.and("ipv6Gateway", 
AllFieldsSearch.entity().getIPv6Gateway(), Op.EQ);
         AllFieldsSearch.and("ipv6Cidr", 
AllFieldsSearch.entity().getIPv6Cidr(), Op.EQ);
@@ -427,6 +428,16 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, 
Long> implements NicDao {
         return findOneBy(sc);
     }
 
+    @Override
+    public List<NicVO> listByMacAddresses(List<String> macAddresses) {
+        if (CollectionUtils.isEmpty(macAddresses)) {
+            return Collections.emptyList();
+        }
+        SearchCriteria<NicVO> sc = AllFieldsSearch.create();
+        sc.setParameters("macAddress", macAddresses.toArray());
+        return listBy(sc);
+    }
+
     @Override
     public List<NicVO> findNicsByIpv6GatewayIpv6CidrAndReserver(String 
ipv6Gateway, String ipv6Cidr, String reserverName) {
         SearchCriteria<NicVO> sc = AllFieldsSearch.create();
diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java 
b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
index 83cce4351b2..5c9d54e1937 100644
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@ -5195,11 +5195,31 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
                             return;
                         }
 
+                        List<String> macAddresses = new 
ArrayList<>(vmNetworkStats.size());
+                        for (VmNetworkStatsEntry entry : vmNetworkStats) {
+                            macAddresses.add(entry.getMacAddress());
+                        }
+                        Map<String, NicVO> nicsByMac = new HashMap<>();
+                        for (NicVO nic : 
_nicDao.listByMacAddresses(macAddresses)) {
+                            nicsByMac.put(nic.getMacAddress(), nic);
+                        }
+
+                        Set<Long> networkIds = new HashSet<>();
+                        for (NicVO nic : nicsByMac.values()) {
+                            networkIds.add(nic.getNetworkId());
+                        }
+                        Map<Long, List<VlanVO>> vlansByNetwork = new 
HashMap<>();
+                        for (VlanVO vlan : _vlanDao.listVlansByNetworkIds(new 
ArrayList<>(networkIds))) {
+                            
vlansByNetwork.computeIfAbsent(vlan.getNetworkId(), k -> new 
ArrayList<>()).add(vlan);
+                        }
+
                         for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) 
{
-                            SearchCriteria<NicVO> sc_nic = 
_nicDao.createSearchCriteria();
-                            sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, 
vmNetworkStat.getMacAddress());
-                            NicVO nic = _nicDao.search(sc_nic, null).get(0);
-                            List<VlanVO> vlan = 
_vlanDao.listVlansByNetworkId(nic.getNetworkId());
+                            NicVO nic = 
nicsByMac.get(vmNetworkStat.getMacAddress());
+                            if (nic == null) {
+                                logger.warn("Unable to find nic for mac " + 
vmNetworkStat.getMacAddress());
+                                continue;
+                            }
+                            List<VlanVO> vlan = 
vlansByNetwork.get(nic.getNetworkId());
                             if (vlan == null || vlan.size() == 0 || 
vlan.get(0).getVlanType() != VlanType.DirectAttached)
                             {
                                 break; // only get network statistics for 
DirectAttached network (shared networks in Basic zone and Advanced zone 
with/without SG)

Reply via email to