def range_search(self, data, filters):
        """Perform integer range searches across a list of dictionaries.

        Given a list of dictionaries, search across the list using the given
        dictionary keys and a range of integer values for each key. Only
        dictionaries that match ALL search filters across the entire original
        data set will be returned.

        It is not a requirement that each dictionary contain the key used
        for searching. Those without the key will be considered non-matching.

        The range values must be string values and is either a set of digits
        representing an integer for matching, or a range operator followed by
        a set of digits representing an integer for matching. If a range
        operator is not given, exact value matching will be used. Valid
        operators are one of: <,>,<=,>=

        :param data: List of dictionaries to be searched.
        :param filters: Dict describing the one or more range searches to
            perform. If more than one search is given, the result will be the
            members of the original data set that match ALL searches. An
            example of filtering by multiple ranges::

                {"vcpus": "<=5", "ram": "<=2048", "disk": "1"}

        :returns: A list subset of the original data set.
        :raises: OpenStackCloudException on invalid range expressions.
        """
        filtered = []

        for key, range_value in filters.items():
            # We always want to operate on the full data set so that
            # calculations for minimum and maximum are correct.
            results = _utils.range_filter(data, key, range_value)

            if not filtered:
                # First set of results
                filtered = results
            else:
                # The combination of all searches should be the intersection of
                # all result sets from each search. So adjust the current set
                # of filtered data by computing its intersection with the
                # latest result set.
                filtered = [r for r in results for f in filtered if r == f]

        return filtered
Exemple #2
0
    def range_search(self, data, filters):
        """Perform integer range searches across a list of dictionaries.

        Given a list of dictionaries, search across the list using the given
        dictionary keys and a range of integer values for each key. Only
        dictionaries that match ALL search filters across the entire original
        data set will be returned.

        It is not a requirement that each dictionary contain the key used
        for searching. Those without the key will be considered non-matching.

        The range values must be string values and is either a set of digits
        representing an integer for matching, or a range operator followed by
        a set of digits representing an integer for matching. If a range
        operator is not given, exact value matching will be used. Valid
        operators are one of: <,>,<=,>=

        :param data: List of dictionaries to be searched.
        :param filters: Dict describing the one or more range searches to
            perform. If more than one search is given, the result will be the
            members of the original data set that match ALL searches. An
            example of filtering by multiple ranges::

                {"vcpus": "<=5", "ram": "<=2048", "disk": "1"}

        :returns: A list subset of the original data set.
        :raises: OpenStackCloudException on invalid range expressions.
        """
        filtered = []

        for key, range_value in filters.items():
            # We always want to operate on the full data set so that
            # calculations for minimum and maximum are correct.
            results = _utils.range_filter(data, key, range_value)

            if not filtered:
                # First set of results
                filtered = results
            else:
                # The combination of all searches should be the intersection of
                # all result sets from each search. So adjust the current set
                # of filtered data by computing its intersection with the
                # latest result set.
                filtered = [r for r in results for f in filtered if r == f]

        return filtered
 def test_range_filter_invalid_op(self):
     with testtools.ExpectedException(
         exc.OpenStackCloudException,
         "Invalid range value: <>100"
     ):
         _utils.range_filter(RANGE_DATA, "key1", "<>100")
 def test_range_filter_exact(self):
     retval = _utils.range_filter(RANGE_DATA, "key1", "2")
     self.assertIsInstance(retval, list)
     self.assertEqual(2, len(retval))
     self.assertEqual(RANGE_DATA[2:4], retval)
 def test_range_filter_range(self):
     retval = _utils.range_filter(RANGE_DATA, "key1", "<3")
     self.assertIsInstance(retval, list)
     self.assertEqual(4, len(retval))
     self.assertEqual(RANGE_DATA[:4], retval)
 def test_range_filter_max(self):
     retval = _utils.range_filter(RANGE_DATA, "key1", "max")
     self.assertIsInstance(retval, list)
     self.assertEqual(2, len(retval))
     self.assertEqual(RANGE_DATA[-2:], retval)
Exemple #7
0
 def test_range_filter_invalid_op(self):
     with testtools.ExpectedException(exc.OpenStackCloudException,
                                      "Invalid range value: <>100"):
         _utils.range_filter(RANGE_DATA, "key1", "<>100")
Exemple #8
0
 def test_range_filter_exact(self):
     retval = _utils.range_filter(RANGE_DATA, "key1", "2")
     self.assertIsInstance(retval, list)
     self.assertEqual(2, len(retval))
     self.assertEqual(RANGE_DATA[2:4], retval)
Exemple #9
0
 def test_range_filter_range(self):
     retval = _utils.range_filter(RANGE_DATA, "key1", "<3")
     self.assertIsInstance(retval, list)
     self.assertEqual(4, len(retval))
     self.assertEqual(RANGE_DATA[:4], retval)
Exemple #10
0
 def test_range_filter_max(self):
     retval = _utils.range_filter(RANGE_DATA, "key1", "max")
     self.assertIsInstance(retval, list)
     self.assertEqual(2, len(retval))
     self.assertEqual(RANGE_DATA[-2:], retval)