diff --git a/neat/locals/overload/trivial.py b/neat/locals/overload/trivial.py index 410d84d..d97e5bf 100644 --- a/neat/locals/overload/trivial.py +++ b/neat/locals/overload/trivial.py @@ -62,6 +62,29 @@ def threshold_factory(time_step, migration_time, params): {}) +@contract +def last_n_average_threshold_factory(time_step, migration_time, params): + """ Creates the averaging CPU utilization threshold algorithm. + + :param time_step: The length of the simulation time step in seconds. + :type time_step: int,>=0 + + :param migration_time: The VM migration time in time seconds. + :type migration_time: float,>=0 + + :param params: A dictionary containing the algorithm's parameters. + :type params: dict(str: *) + + :return: A function implementing the averaging threshold algorithm. + :rtype: function + """ + return lambda utilization, state=None: ( + last_n_average_threshold(params['threshold'], + params['n'], + utilization), + {}) + + @contract def threshold(threshold, utilization): """ The static CPU utilization threshold algorithm. @@ -78,3 +101,25 @@ def threshold(threshold, utilization): if utilization: return utilization[-1] > threshold return False + + +@contract +def last_n_average_threshold(threshold, n, utilization): + """ The averaging CPU utilization threshold algorithm. + + :param threshold: The threshold on the CPU utilization. + :type threshold: float,>=0 + + :param n: The number of last CPU utilization values to average. + :type n: int,>0 + + :param utilization: The history of the host's CPU utilization. + :type utilization: list(float) + + :return: The decision of the algorithm. + :rtype: bool + """ + if utilization: + utilization = utilization[-n:] + return sum(utilization) / len(utilization) > threshold + return False diff --git a/tests/locals/overload/test_trivial.py b/tests/locals/overload/test_trivial.py index e27b332..adbdda3 100644 --- a/tests/locals/overload/test_trivial.py +++ b/tests/locals/overload/test_trivial.py @@ -33,13 +33,6 @@ class Trivial(TestCase): {'threshold': 0.5}) assert alg(utilization) == (False, {}) - def test_threshold(self): - self.assertTrue(trivial.threshold(0.5, [0.9, 0.8, 1.1, 1.2, 1.3])) - self.assertTrue(trivial.threshold(0.5, [0.9, 0.8, 1.1, 1.2, 0.6])) - self.assertFalse(trivial.threshold(0.5, [0.9, 0.8, 1.1, 1.2, 0.5])) - self.assertFalse(trivial.threshold(0.5, [0.9, 0.8, 1.1, 1.2, 0.3])) - self.assertFalse(trivial.threshold(0.5, [])) - def test_threshold_factory(self): alg = trivial.threshold_factory(300, 20., {'threshold': 0.5}) self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 1.3]), (True, {})) @@ -47,3 +40,52 @@ class Trivial(TestCase): self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 0.5]), (False, {})) self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 0.3]), (False, {})) self.assertEquals(alg([]), (False, {})) + + def test_last_n_average_threshold_factory(self): + alg = trivial.last_n_average_threshold_factory( + 300, 20., {'threshold': 0.5, 'n': 1}) + self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 1.3]), (True, {})) + self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 0.6]), (True, {})) + self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 0.5]), (False, {})) + self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 0.3]), (False, {})) + self.assertEquals(alg([]), (False, {})) + + alg = trivial.last_n_average_threshold_factory( + 300, 20., {'threshold': 0.5, 'n': 2}) + self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 1.3]), (True, {})) + self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 0.6]), (True, {})) + self.assertEquals(alg([0.9, 0.8, 1.1, 1.2, 0.4]), (True, {})) + self.assertEquals(alg([0.9, 0.8, 1.1, 0.4, 0.5]), (False, {})) + self.assertEquals(alg([0.9, 0.8, 1.1, 0.2, 0.3]), (False, {})) + self.assertEquals(alg([]), (False, {})) + + def test_threshold(self): + self.assertTrue(trivial.threshold(0.5, [0.9, 0.8, 1.1, 1.2, 1.3])) + self.assertTrue(trivial.threshold(0.5, [0.9, 0.8, 1.1, 1.2, 0.6])) + self.assertFalse(trivial.threshold(0.5, [0.9, 0.8, 1.1, 1.2, 0.5])) + self.assertFalse(trivial.threshold(0.5, [0.9, 0.8, 1.1, 1.2, 0.3])) + self.assertFalse(trivial.threshold(0.5, [])) + + def test_last_n_average_threshold(self): + self.assertTrue(trivial.last_n_average_threshold( + 0.5, 1, [0.9, 0.8, 1.1, 1.2, 1.3])) + self.assertTrue(trivial.last_n_average_threshold( + 0.5, 1, [0.9, 0.8, 1.1, 1.2, 0.6])) + self.assertFalse(trivial.last_n_average_threshold( + 0.5, 1, [0.9, 0.8, 1.1, 1.2, 0.5])) + self.assertFalse(trivial.last_n_average_threshold( + 0.5, 1, [0.9, 0.8, 1.1, 1.2, 0.3])) + self.assertFalse(trivial.last_n_average_threshold( + 0.5, 1, [])) + + self.assertTrue(trivial.last_n_average_threshold( + 0.5, 2, [0.9, 0.8, 1.1, 1.2, 1.3])) + self.assertTrue(trivial.last_n_average_threshold( + 0.5, 2, [0.9, 0.8, 1.1, 1.2, 0.6])) + self.assertTrue(trivial.last_n_average_threshold( + 0.5, 2, [0.9, 0.8, 1.1, 1.2, 0.4])) + self.assertFalse(trivial.last_n_average_threshold( + 0.5, 2, [0.9, 0.8, 1.1, 0.4, 0.5])) + self.assertFalse(trivial.last_n_average_threshold( + 0.5, 2, [0.9, 0.8, 1.1, 0.2, 0.3])) + self.assertFalse(trivial.last_n_average_threshold(0.5, 2, []))