Improve performance of _get_security_group_member_ips
Use set operations instead of using list. Currently complexity of the method is O(n^2) where n is amount of ips (amount of VMs in the network). When amount of VM is big (large L2 domain), this method can significantly load the controller. Reduce method complexity to O(n) on average. Change-Id: If1660e8227e5c5cd80d49ebcc6a2e06d33d31939 Closes-Bug: #1429753
This commit is contained in:
parent
ebc1469a7e
commit
2db7182570
|
@ -71,9 +71,11 @@ class SecurityGroupServerRpcCallback(object):
|
|||
:returns:
|
||||
sg_info{
|
||||
'security_groups': {sg_id: [rule1, rule2]}
|
||||
'sg_member_ips': {sg_id: {'IPv4': [], 'IPv6': []}}
|
||||
'sg_member_ips': {sg_id: {'IPv4': set(), 'IPv6': set()}}
|
||||
'devices': {device_id: {device_info}}
|
||||
}
|
||||
|
||||
Note that sets are serialized into lists by rpc code.
|
||||
"""
|
||||
devices_info = kwargs.get('devices')
|
||||
ports = self._get_devices_info(devices_info)
|
||||
|
|
|
@ -194,7 +194,8 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
|
|||
if remote_gid not in remote_security_group_info:
|
||||
remote_security_group_info[remote_gid] = {}
|
||||
if ethertype not in remote_security_group_info[remote_gid]:
|
||||
remote_security_group_info[remote_gid][ethertype] = []
|
||||
# this set will be serialized into a list by rpc code
|
||||
remote_security_group_info[remote_gid][ethertype] = set()
|
||||
|
||||
direction = rule_in_db['direction']
|
||||
rule_dict = {
|
||||
|
@ -228,9 +229,8 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
|
|||
for sg_id, member_ips in ips.items():
|
||||
for ip in member_ips:
|
||||
ethertype = 'IPv%d' % netaddr.IPNetwork(ip).version
|
||||
if (ethertype in sg_info['sg_member_ips'][sg_id]
|
||||
and ip not in sg_info['sg_member_ips'][sg_id][ethertype]):
|
||||
sg_info['sg_member_ips'][sg_id][ethertype].append(ip)
|
||||
if ethertype in sg_info['sg_member_ips'][sg_id]:
|
||||
sg_info['sg_member_ips'][sg_id][ethertype].add(ip)
|
||||
return sg_info
|
||||
|
||||
def _select_rules_for_ports(self, context, ports):
|
||||
|
|
|
@ -490,8 +490,8 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase):
|
|||
'remote_group_id': sg2_id}
|
||||
]},
|
||||
'sg_member_ips': {sg2_id: {
|
||||
'IPv4': [u'10.0.0.3'],
|
||||
'IPv6': [],
|
||||
'IPv4': set([u'10.0.0.3']),
|
||||
'IPv6': set(),
|
||||
}}
|
||||
}
|
||||
self.assertEqual(expected['security_groups'],
|
||||
|
@ -626,7 +626,7 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase):
|
|||
'remote_group_id': sg1_id}
|
||||
]},
|
||||
'sg_member_ips': {sg1_id: {
|
||||
'IPv6': [],
|
||||
'IPv6': set(),
|
||||
}}
|
||||
}
|
||||
self.assertEqual(expected['security_groups'],
|
||||
|
|
Loading…
Reference in New Issue