instrumentation: add next-share/
[cs-p2p-next.git] / instrumentation / next-share / BaseLib / Core / ProxyService / RatePredictor.py
1 # Written by Pawel Garbacki, George Milescu
2 # see LICENSE.txt for license information
3
4 import sys
5 from BaseLib.Core.BitTornado.clock import clock
6
7 MIN_CAPACITY = 0.75
8 DEBUG = False
9
10 class RatePredictor:
11     def __init__(self, raw_server, rate_measure, max_rate, probing_period = 2):
12         self.raw_server = raw_server
13         self.rate_measure = rate_measure
14         if max_rate == 0:   
15             self.max_rate = 2147483647
16         else:
17             self.max_rate = max_rate
18         self.probing_period = probing_period # in seconds
19
20 class ExpSmoothRatePredictor(RatePredictor):
21     def __init__(self, raw_server, rate_measure, max_rate, alpha = 0.5, max_period = 30, probing_period = 2):
22         RatePredictor.__init__(self, raw_server, rate_measure, max_rate, probing_period)
23         if DEBUG: print >>sys.stderr, "RatePredictor:__init__"
24         self.alpha = alpha
25         self.max_period = max_period
26         self.value = None
27         self.timestamp = None
28
29     def update(self):
30         if DEBUG: print >>sys.stderr, "RatePredictor:update"
31         self.raw_server.add_task(self.update, self.probing_period)
32         current_value = self.rate_measure.get_rate() / 1000.
33         current_time = clock()
34         if self.value is None or current_time - self.timestamp > self.max_period:
35             self.value = current_value
36         else:
37             self.value = self.alpha * current_value + (1 - self.alpha) * self.value
38             if self.max_rate > 0 and self.value > self.max_rate:
39                 self.value = self.max_rate
40         self.timestamp = current_time
41
42     # exponential smoothing prediction
43     def predict(self):
44         if DEBUG: print >>sys.stderr, "RatePredictor:predict"
45         # self.update()
46         if self.value is None:
47             return 0
48         return self.value
49
50     def has_capacity(self):
51         if DEBUG: print >>sys.stderr, "RatePredictor:has_capacity"
52 #        return False
53         # self.update()
54         result = None
55         if self.value is None:
56             result = True
57         else:
58             result = (1. - float(self.value) / self.max_rate) > MIN_CAPACITY
59         return result