[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [sbws/master] Move functions to methods
commit a98787cface97bb7e248e2e4a98123d5425ef9dd
Author: juga0 <juga@xxxxxxxxxx>
Date: Wed Aug 29 17:35:23 2018 +0000
Move functions to methods
---
sbws/lib/v3bwfile.py | 93 +++++++++++++++++++++++++++++++++-------------------
1 file changed, 59 insertions(+), 34 deletions(-)
diff --git a/sbws/lib/v3bwfile.py b/sbws/lib/v3bwfile.py
index ef9eadc..42e318c 100644
--- a/sbws/lib/v3bwfile.py
+++ b/sbws/lib/v3bwfile.py
@@ -2,12 +2,13 @@
"""Classes and functions that create the bandwidth measurements document
(v3bw) used by bandwidth authorities."""
+import copy
import logging
import os
-from statistics import median
+from statistics import median, mean
from sbws import __version__
-from sbws.globals import SPEC_VERSION, BW_LINE_SIZE
+from sbws.globals import SPEC_VERSION, BW_LINE_SIZE, SCALE_CONSTANT
from sbws.lib.resultdump import ResultSuccess, _ResultType
from sbws.util.filelock import DirectoryLock
from sbws.util.timestamp import now_isodt_str, unixts_to_isodt_str
@@ -40,33 +41,6 @@ BW_KEYVALUES_INT = ['bw', 'rtt', 'success', 'error_stream',
BW_KEYVALUES = ['node_id', 'bw'] + BW_EXTRA_ARG_KEYVALUES
-def total_bw(bw_lines):
- return sum([l.bw for l in bw_lines])
-
-
-def avg_bw(bw_lines):
- assert len(bw_lines) > 0
- return total_bw(bw_lines) / len(bw_lines)
-
-
-def scale_lines(bw_lines, scale_constant):
- avg = avg_bw(bw_lines)
- for line in bw_lines:
- line.bw = round(line.bw / avg * scale_constant)
- warn_if_not_accurate_enough(bw_lines, scale_constant)
- return bw_lines
-
-
-def warn_if_not_accurate_enough(bw_lines, scale_constant):
- margin = 0.001
- accuracy_ratio = avg_bw(bw_lines) / scale_constant
- log.info('The generated lines are within {:.5}% of what they should '
- 'be'.format((1 - accuracy_ratio) * 100))
- if accuracy_ratio < 1 - margin or accuracy_ratio > 1 + margin:
- log.warning('There was %f%% error and only +/- %f%% is '
- 'allowed', (1 - accuracy_ratio) * 100, margin * 100)
-
-
def num_results_of_type(results, type_str):
return len([r for r in results if r.type == type_str])
@@ -387,17 +361,68 @@ class V3BWFile(object):
f = cls(header, bw_lines)
return f
+ @staticmethod
+ def bw_sbws_scale(bw_lines, scale_constant=SCALE_CONSTANT,
+ reverse=False):
+ """Return a new V3BwLine list scaled using sbws method.
+
+ :param list bw_lines:
+ bw lines to scale, not self.bw_lines,
+ since this method will be before self.bw_lines have been
+ initialized.
+ :param int scale_constant:
+ the constant to multiply by the ratio and
+ the bandwidth to obtain the new bandwidth
+ :returns list: V3BwLine list
+ """
+ # If a relay has MaxAdvertisedBandwidth set, they may be capable of
+ # some large amount of bandwidth but prefer if they didn't receive it.
+ # We also could have managed to measure them faster than their
+ # {,Relay}BandwidthRate somehow.
+ #
+ # See https://github.com/pastly/simple-bw-scanner/issues/155 and
+ # https://trac.torproject.org/projects/tor/ticket/8494
+ #
+ # Note how this isn't some measured-by-us average of bandwidth. It's
+ # the first value on the 'bandwidth' line in the relay's server
+ # descriptor.
+ log.debug('Scaling bandwidth using sbws method.')
+ m = median([l.bw for l in bw_lines])
+ bw_lines_scaled = copy.deepcopy(bw_lines)
+ for l in bw_lines_scaled:
+ # min is to limit the bw to descriptor average-bandwidth
+ # max to avoid bandwidth with 0 value
+ l.bw = max(round(min(l.desc_avg_bw_bs,
+ l.bw_bs_median * scale_constant / m)
+ / 1000), 1)
+ return sorted(bw_lines_scaled, key=lambda x: x.bw, reverse=reverse)
+
+ @staticmethod
+ def warn_if_not_accurate_enough(bw_lines,
+ scale_constant=SCALE_CONSTANT):
+ margin = 0.001
+ accuracy_ratio = median([l.bw for l in bw_lines]) / scale_constant
+ log.info('The generated lines are within {:.5}% of what they should '
+ 'be'.format((1 - accuracy_ratio) * 100))
+ if accuracy_ratio < 1 - margin or accuracy_ratio > 1 + margin:
+ log.warning('There was %f%% error and only +/- %f%% is '
+ 'allowed', (1 - accuracy_ratio) * 100, margin * 100)
+
@property
- def total_bw(self):
- return total_bw(self.bw_lines)
+ def sum_bw(self):
+ return sum([l.bw for l in self.bw_lines])
@property
- def num_lines(self):
+ def num(self):
return len(self.bw_lines)
@property
- def avg_bw(self):
- return self.total_bw / self.num_lines
+ def mean_bw(self):
+ return mean([l.bw for l in self.bw_lines])
+
+ @property
+ def median_bw(self):
+ return median([l.bw for l in self.bw_lines])
def write(self, output):
if output == '/dev/stdout':
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits