Add a rw_ctx.psum_res_by_rp_rc, for clarity
In _merge_candidates we need a final _exceeds_capacity check to make sure a multi-part granular request has not exceeded capacity limits. This uses a dict that maps resource provider uuid and resource class name to a ProviderSummaryResource. Rather than creating this dict in _merge_candidates, we now have it as a member on the RequestWideSearchContext and add to it when creating the ProviderSummaryResource. This allows us to remove some looping in _merge_candidates and is also a bit more tidy. This is only possible with the advent of the RequestWideSearchContext, which is newer than _merge_candidates. _exceeds_capacity is moved to the RequestWideSearchContext as exceeds_capacity as it now makes sense as a method. Because _rp_rc_key ended up used from two different modules and for two different purposes, the method is instead removed and callers create their own keys directly. Change-Id: Id74c01215956fc998f2dadcd9d84801ac58c2d3d
This commit is contained in:
parent
803d673c1f
commit
5dda479f5b
@ -571,6 +571,11 @@ def _build_provider_summaries(context, rw_ctx, prov_traits):
|
||||
used=used,
|
||||
max_unit=usage['max_unit'],
|
||||
)
|
||||
# Construct a dict, keyed by resource provider + resource class, of
|
||||
# ProviderSummaryResource. This will be used to do a final capacity
|
||||
# check/filter on each merged AllocationRequest.
|
||||
psum_key = (rp_id, rc_name)
|
||||
rw_ctx.psum_res_by_rp_rc[psum_key] = rpsr
|
||||
summary.resources.append(rpsr)
|
||||
|
||||
|
||||
@ -653,7 +658,7 @@ def _consolidate_allocation_requests(areqs, rw_ctx):
|
||||
"`_consolidate_allocation_requests` to have the same "
|
||||
"anchor!")
|
||||
for arr in areq.resource_requests:
|
||||
key = _rp_rc_key(arr.resource_provider, arr.resource_class)
|
||||
key = (arr.resource_provider.id, arr.resource_class)
|
||||
if key not in arrs_by_rp_rc:
|
||||
arrs_by_rp_rc[key] = rw_ctx.copy_arr_if_needed(arr)
|
||||
else:
|
||||
@ -666,39 +671,6 @@ def _consolidate_allocation_requests(areqs, rw_ctx):
|
||||
mappings=mappings)
|
||||
|
||||
|
||||
def _exceeds_capacity(areq, psum_res_by_rp_rc):
|
||||
"""Checks a (consolidated) AllocationRequest against the provider summaries
|
||||
to ensure that it does not exceed capacity.
|
||||
|
||||
Exceeding capacity can mean the total amount (already used plus this
|
||||
allocation) exceeds the total inventory amount; or this allocation exceeds
|
||||
the max_unit in the inventory record.
|
||||
|
||||
:param areq: An AllocationRequest produced by the
|
||||
`_consolidate_allocation_requests` method.
|
||||
:param psum_res_by_rp_rc: A dict, keyed by provider + resource class via
|
||||
_rp_rc_key, of ProviderSummaryResource.
|
||||
:return: True if areq exceeds capacity; False otherwise.
|
||||
"""
|
||||
for arr in areq.resource_requests:
|
||||
key = _rp_rc_key(arr.resource_provider, arr.resource_class)
|
||||
psum_res = psum_res_by_rp_rc[key]
|
||||
if psum_res.used + arr.amount > psum_res.capacity:
|
||||
LOG.debug('Excluding the following AllocationRequest because used '
|
||||
'(%d) + amount (%d) > capacity (%d) for resource class '
|
||||
'%s: %s',
|
||||
psum_res.used, arr.amount, psum_res.capacity,
|
||||
arr.resource_class, str(areq))
|
||||
return True
|
||||
if arr.amount > psum_res.max_unit:
|
||||
LOG.debug('Excluding the following AllocationRequest because '
|
||||
'amount (%d) > max_unit (%d) for resource class %s: %s',
|
||||
arr.amount, psum_res.max_unit, arr.resource_class,
|
||||
str(areq))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# TODO(efried): Move _merge_candidates to rw_ctx?
|
||||
def _merge_candidates(candidates, rw_ctx):
|
||||
"""Given a dict, keyed by RequestGroup suffix, of tuples of
|
||||
@ -736,20 +708,12 @@ def _merge_candidates(candidates, rw_ctx):
|
||||
lambda: collections.defaultdict(list))
|
||||
# Save off all the provider summaries lists - we'll use 'em later.
|
||||
all_psums = []
|
||||
# Construct a dict, keyed by resource provider + resource class, of
|
||||
# ProviderSummaryResource. This will be used to do a final capacity
|
||||
# check/filter on each merged AllocationRequest.
|
||||
psum_res_by_rp_rc = {}
|
||||
for suffix, (areqs, psums) in candidates.items():
|
||||
for areq in areqs:
|
||||
anchor = areq.anchor_root_provider_uuid
|
||||
areq_lists_by_anchor[anchor][suffix].append(areq)
|
||||
for psum in psums:
|
||||
all_psums.append(psum)
|
||||
for psum_res in psum.resources:
|
||||
key = _rp_rc_key(
|
||||
psum.resource_provider, psum_res.resource_class)
|
||||
psum_res_by_rp_rc[key] = psum_res
|
||||
|
||||
# Create all combinations picking one AllocationRequest from each list
|
||||
# for each anchor.
|
||||
@ -811,8 +775,7 @@ def _merge_candidates(candidates, rw_ctx):
|
||||
# *independent* queries, it's possible that the combined result
|
||||
# now exceeds capacity where amounts of the same RP+RC were
|
||||
# folded together. So do a final capacity check/filter.
|
||||
# TODO(efried): Move _exceeds_capacity to rw_ctx?
|
||||
if _exceeds_capacity(areq, psum_res_by_rp_rc):
|
||||
if rw_ctx.exceeds_capacity(areq):
|
||||
continue
|
||||
areqs.add(areq)
|
||||
|
||||
@ -836,11 +799,6 @@ def _merge_candidates(candidates, rw_ctx):
|
||||
return list(areqs), psums
|
||||
|
||||
|
||||
def _rp_rc_key(rp, rc):
|
||||
"""Creates hashable key unique to a provider + resource class."""
|
||||
return rp.id, rc
|
||||
|
||||
|
||||
def _satisfies_group_policy(areqs, group_policy, num_granular_groups):
|
||||
"""Applies group_policy to a list of AllocationRequest.
|
||||
|
||||
|
@ -212,6 +212,10 @@ class RequestWideSearchContext(object):
|
||||
# A mapping of resource provider uuid to parent provider uuid, used
|
||||
# when merging allocation candidates.
|
||||
self.parent_uuid_by_rp_uuid = {}
|
||||
# Dict mapping (resource provier uuid, resource class name) to a
|
||||
# ProviderSummaryResource. Used during _exceeds_capacity in
|
||||
# _merge_candidates.
|
||||
self.psum_res_by_rp_rc = {}
|
||||
|
||||
def _process_anchor_traits(self, rqparams):
|
||||
"""Set or filter self.anchor_root_ids according to anchor
|
||||
@ -358,6 +362,37 @@ class RequestWideSearchContext(object):
|
||||
return copy.copy(arr)
|
||||
return arr
|
||||
|
||||
def exceeds_capacity(self, areq):
|
||||
"""Checks a (consolidated) AllocationRequest against the provider
|
||||
summaries to ensure that it does not exceed capacity.
|
||||
|
||||
Exceeding capacity can mean the total amount (already used plus this
|
||||
allocation) exceeds the total inventory amount; or this allocation
|
||||
exceeds the max_unit in the inventory record.
|
||||
|
||||
:param areq: An AllocationRequest produced by the
|
||||
`_consolidate_allocation_requests` method.
|
||||
:return: True if areq exceeds capacity; False otherwise.
|
||||
"""
|
||||
for arr in areq.resource_requests:
|
||||
key = (arr.resource_provider.id, arr.resource_class)
|
||||
psum_res = self.psum_res_by_rp_rc[key]
|
||||
if psum_res.used + arr.amount > psum_res.capacity:
|
||||
LOG.debug('Excluding the following AllocationRequest because '
|
||||
'used (%d) + amount (%d) > capacity (%d) for '
|
||||
'resource class %s: %s',
|
||||
psum_res.used, arr.amount, psum_res.capacity,
|
||||
arr.resource_class, str(areq))
|
||||
return True
|
||||
if arr.amount > psum_res.max_unit:
|
||||
LOG.debug('Excluding the following AllocationRequest because '
|
||||
'amount (%d) > max_unit (%d) for resource class '
|
||||
'%s: %s',
|
||||
arr.amount, psum_res.max_unit, arr.resource_class,
|
||||
str(areq))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@db_api.placement_context_manager.reader
|
||||
def provider_ids_from_uuid(context, uuid):
|
||||
|
Loading…
Reference in New Issue
Block a user