Files
placement/placement/objects/rp_candidates.py
T
Stephen Finucane aa520fec9c pre-commit: Add autopep8
Change-Id: Ie0d191d6b4d5620c014cceddbb885c901a500d79
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
2024-07-04 11:13:36 +01:00

109 lines
3.8 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Utility methods for getting allocation candidates."""
import collections
RPCandidate = collections.namedtuple('RPCandidates', 'id root_id rc_id')
class RPCandidateList(object):
"""Helper class to manage allocation candidate resource providers list,
RPCandidates, which consists of three-tuples with the first element being
the resource provider ID, the second element being the root provider ID
and the third being resource class ID.
"""
def __init__(self, rp_candidates=None):
self.rp_candidates = rp_candidates or set()
def __len__(self):
return len(self.rp_candidates)
def __bool__(self):
return bool(len(self))
def __nonzero__(self):
return self.__bool__()
def merge_common_trees(self, other):
"""Merge two RPCandidateLists by OR'ing the two list of candidates
and if the tree is not in both RPCandidateLists, we exclude resource
providers in that tree. This is used to get trees that can satisfy
all requested resource.
"""
if not self:
self.rp_candidates = other.rp_candidates
elif not other:
pass
else:
trees_in_both = self.trees & other.trees
self.rp_candidates |= other.rp_candidates
self.filter_by_tree(trees_in_both)
def add_rps(self, rps, rc_id):
"""Add given resource providers to the candidate list.
:param rps: tuples of (resource provider ID, anchor root provider ID)
:param rc_id: ID of the class of resource provided by these resource
providers
"""
self.rp_candidates |= set(
RPCandidate(id=rp[0], root_id=rp[1], rc_id=rc_id) for rp in rps)
def filter_by_tree(self, tree_root_ids):
"""Filter the candidates by given trees"""
self.rp_candidates = set(
p for p in self.rp_candidates if p.root_id in tree_root_ids)
def filter_by_rp(self, rptuples):
"""Filter the candidates by given resource provider"""
self.rp_candidates = set(
p for p in self.rp_candidates if (p.id, p.root_id) in rptuples)
def filter_by_rp_or_tree(self, rp_ids):
"""Filter the candidates out if neither itself nor its root is in
given resource providers
"""
self.rp_candidates = set(
p for p in self.rp_candidates if set([p.id, p.root_id]) & rp_ids)
def filter_by_rp_nor_tree(self, rp_ids):
"""Filter the candidates out if either itself or its root is in
given resource providers
"""
self.rp_candidates = set(
p for p in self.rp_candidates if not (
set([p.id, p.root_id]) & rp_ids))
@property
def rps(self):
"""Returns a set of IDs of nominated resource providers"""
return set(p.id for p in self.rp_candidates)
@property
def trees(self):
"""Returns a set of nominated trees each of which are expressed by
the root provider ID
"""
return set(p.root_id for p in self.rp_candidates)
@property
def all_rps(self):
"""Returns a set of IDs of all involved resource providers"""
return (self.rps | self.trees)
@property
def rps_info(self):
return self.rp_candidates