From f8bbda15e7d16cd27697fcf6a9d52d8233c77be3 Mon Sep 17 00:00:00 2001 From: Tetsuro Nakamura Date: Thu, 16 May 2019 06:17:29 +0000 Subject: [PATCH] Move seek providers with resource to context This patch moves the resource look up to `RequestGroupSearchContext` initialization. This enables us to reuse the results for _get_providers_with_shared_capacity(). That optimization is coming in a following patch. Change-Id: I2796c3e93317edd3ae8b02fb038cc39f23b41840 Story: 2005712 Task: 31038 --- placement/objects/research_context.py | 22 +++++++++++++++---- .../db/test_allocation_candidates.py | 19 ++++++++++------ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/placement/objects/research_context.py b/placement/objects/research_context.py index 14cefa3bd..85396943e 100644 --- a/placement/objects/research_context.py +++ b/placement/objects/research_context.py @@ -106,6 +106,19 @@ class RequestGroupSearchContext(object): LOG.debug("getting allocation candidates in the same tree " "with the root provider %s", tree_ids.root_uuid) + self._rps_with_resource = {} + for rc_id, amount in self.resources.items(): + # NOTE(tetsuro): We could pass rps in requested aggregates to + # get_providers_with_resource here once we explicitly put + # aggregates to nested (non-root) providers (the aggregate + # flows down feature) rather than applying later the implicit rule + # that aggregate on root spans the whole tree + provs_with_resource = get_providers_with_resource( + context, rc_id, amount, tree_root_id=self.tree_root_id) + if not provs_with_resource: + raise exception.ResourceProviderNotFound() + self._rps_with_resource[rc_id] = provs_with_resource + # a dict, keyed by resource class ID, of the set of resource # provider IDs that share some inventory for each resource class # This is only used for unnumbered request group path where @@ -143,6 +156,9 @@ class RequestGroupSearchContext(object): def get_rps_with_shared_capacity(self, rc_id): return self._sharing_providers.get(rc_id) + def get_rps_with_resource(self, rc_id): + return self._rps_with_resource.get(rc_id) + def provider_ids_from_rp_ids(context, rp_ids): """Given an iterable of internal resource provider IDs, returns a dict, @@ -346,8 +362,7 @@ def get_provider_ids_matching(rg_ctx): first = True for rc_id, amount in rg_ctx.resources.items(): rc_name = rc_cache.RC_CACHE.string_from_id(rc_id) - provs_with_resource = get_providers_with_resource( - rg_ctx.context, rc_id, amount, tree_root_id=rg_ctx.tree_root_id) + provs_with_resource = rg_ctx.get_rps_with_resource(rc_id) LOG.debug("found %d providers with available %d %s", len(provs_with_resource), amount, rc_name) if not provs_with_resource: @@ -435,8 +450,7 @@ def get_trees_matching_all(rg_ctx): rc_name = rc_cache.RC_CACHE.string_from_id(rc_id) provs_with_inv_rc = rp_candidates.RPCandidateList() - rc_provs_with_inv = get_providers_with_resource( - rg_ctx.context, rc_id, amount, tree_root_id=rg_ctx.tree_root_id) + rc_provs_with_inv = rg_ctx.get_rps_with_resource(rc_id) provs_with_inv_rc.add_rps(rc_provs_with_inv, rc_id) LOG.debug("found %d providers under %d trees with available %d %s", len(provs_with_inv_rc), len(provs_with_inv_rc.trees), diff --git a/placement/tests/functional/db/test_allocation_candidates.py b/placement/tests/functional/db/test_allocation_candidates.py index 01c2b023a..060011671 100644 --- a/placement/tests/functional/db/test_allocation_candidates.py +++ b/placement/tests/functional/db/test_allocation_candidates.py @@ -222,13 +222,10 @@ class ProviderDBHelperTestCase(tb.PlacementDbBaseTestCase): # We don't get anything if the specified tree doesn't satisfy the # requirements in the first place - rg_ctx = _req_group_search_context( - self.ctx, - resources=resources, - in_tree=uuids.allused, - ) - res = res_ctx.get_provider_ids_matching(rg_ctx) - self.assertEqual([], res) + self.assertRaises(exception.ResourceProviderNotFound, + _req_group_search_context, + self.ctx, resources=resources, + in_tree=uuids.allused) def test_get_provider_ids_matching_with_multiple_forbidden(self): rp1 = self._create_provider('rp1', uuids.agg1) @@ -417,6 +414,14 @@ class ProviderTreeDBHelperTestCase(tb.PlacementDbBaseTestCase): """Helper function to validate the test result""" # NOTE(jaypipes): get_trees_matching_all() expects a dict of # resource class internal identifiers, not string names + if not expected_trees: + try: + self.assertRaises(exception.ResourceProviderNotFound, + _req_group_search_context, + self.ctx, **kwargs) + return + except Exception: + pass rg_ctx = _req_group_search_context(self.ctx, **kwargs) results = res_ctx.get_trees_matching_all(rg_ctx)