Remove ProviderIds namedtuple

It turns out that all the callers of methods that return ProviderIds
access the data using attributes that are already present on the object
provided by a sql alchemy RowProxy object (which is the result of
iterating a ResultProxy object, returned by sqla.execute()). Creating
a namedtuple is redundant and adds some processing cost [1].

However, the AnchorIds namedtuple used in the same file _is_ necessary
because it provides a hashable type required by the set that wraps
the collection of AnchorIds.

The other user of namedtuple, RPCandidate, in
placement/objects/rp_candidates.py has a specific interface for which
a namedtuple is correct.

[1] provider_ids_from_rp_ids was identified as being a major contributor
when doing performance profiling. Most of the cost is executing with the
database, but the tuple creation is a factor.

Change-Id: I1e1522eae7b4360cf57c34164612ae228fad14a3
This commit is contained in:
Chris Dent 2019-07-31 12:34:30 +01:00 committed by Eric Fried
parent d04168088c
commit 8626b6517b

View File

@ -37,8 +37,6 @@ _RP_TRAIT_TBL = models.ResourceProviderTrait.__table__
LOG = logging.getLogger(__name__)
ProviderIds = collections.namedtuple(
'ProviderIds', 'id uuid parent_id parent_uuid root_id root_uuid')
AnchorIds = collections.namedtuple(
'AnchorIds', 'rp_id rp_uuid anchor_id anchor_uuid')
@ -302,10 +300,9 @@ class RequestWideSearchContext(object):
def provider_ids_from_rp_ids(context, rp_ids):
"""Given an iterable of internal resource provider IDs, returns a dict,
keyed by internal provider Id, of ProviderIds namedtuples describing those
providers.
keyed by internal provider Id, of sqla objects describing those providers.
:returns: dict, keyed by internal provider Id, of ProviderIds namedtuples
:returns: dict, keyed by internal provider Id, of sqla objects
:param rp_ids: iterable of internal provider IDs to look up
"""
# SELECT
@ -338,18 +335,18 @@ def provider_ids_from_rp_ids(context, rp_ids):
ret = {}
for r in context.session.execute(sel):
ret[r['id']] = ProviderIds(**r)
ret[r['id']] = r
return ret
@db_api.placement_context_manager.reader
def provider_ids_from_uuid(context, uuid):
"""Given the UUID of a resource provider, returns a namedtuple
(ProviderIds) with the internal ID, the UUID, the parent provider's
internal ID, parent provider's UUID, the root provider's internal ID and
the root provider UUID.
"""Given the UUID of a resource provider, returns a sqlalchemy object with
the internal ID, the UUID, the parent provider's internal ID, parent
provider's UUID, the root provider's internal ID and the root provider
UUID.
:returns: ProviderIds object containing the internal IDs and UUIDs of the
:returns: sqlalchemy object containing the internal IDs and UUIDs of the
provider identified by the supplied UUID
:param uuid: The UUID of the provider to look up
"""
@ -382,7 +379,7 @@ def provider_ids_from_uuid(context, uuid):
res = context.session.execute(sel).fetchone()
if not res:
return None
return ProviderIds(**dict(res))
return res
def _usage_select(rc_ids):