aa520fec9c
Change-Id: Ie0d191d6b4d5620c014cceddbb885c901a500d79 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
109 lines
3.8 KiB
Python
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
|