+ def binary_search(self, b_min, b_max, traffic_type):
+ """Binary search of rate with loss below acceptance criteria
+
+ :param b_min: min range rate
+ :param b_max: max range rate
+ :param traffic_type: traffic profile
+ :type b_min: float
+ :type b_max: float
+ :type traffic_type: str
+ :return: nothing
+ """
+
+ if not self._rate_min <= float(b_min) <= self._rate_max:
+ raise ValueError("Min rate is not in min,max range")
+ if not self._rate_min <= float(b_max) <= self._rate_max:
+ raise ValueError("Max rate is not in min,max range")
+ if float(b_max) < float(b_min):
+ raise ValueError("Min rate is greater then max rate")
+
+ #binary search
+ #rate is half of interval + start of interval
+ rate = ((float(b_max) - float(b_min)) / 2) + float(b_min)
+ #rate diff with previous run
+ rate_diff = abs(self._last_binary_rate - rate)
+
+ #convergence criterium
+ if float(rate_diff) < float(self._binary_convergence_threshold):
+ if not self._search_result_rate:
+ self._search_result = SearchResults.FAILURE
+ else:
+ self._search_result = SearchResults.SUCCESS
+ return
+
+ self._last_binary_rate = rate
+
+ res = self.measure_loss(rate, self._frame_size,
+ self._loss_acceptance,
+ self._loss_acceptance_type,
+ traffic_type)
+ #loss occured and it was above acceptance criteria
+ if res == False:
+ self.binary_search(b_min, rate, traffic_type)
+ #there was no loss / loss below acceptance criteria
+ elif res == True:
+ self._search_result_rate = rate
+ self.binary_search(rate, b_max, traffic_type)
+ else:
+ raise RuntimeError("Unknown search result")