instrumentation: add next-share/
[cs-p2p-next.git] / instrumentation / next-share / BaseLib / Core / Subtitles / SubtitleHandler / SimpleTokenBucket.py
1 # Written by Andrea Reale
2 # see LICENSE.txt for license information
3
4
5 from time import time
6
7 class SimpleTokenBucket(object):
8     """
9     A simple implementation of a token bucket, to
10     control the rate of subtitles being uploaded.
11     
12     1 token corresponds to 1 KB
13     
14     Not threadsafe!!
15     """
16     
17     def __init__(self, fill_rate, capacity = -1):
18         """
19         Creates a token bucket initialy having 0 tokens,
20         with the given fill_rate.
21         
22         @param fill_rate: number of tokens refilled per second.
23                           a token corrisponds to 1KB
24         @param capacity: maximum number of tokens in the bucket.
25         """
26         
27         #infinite bucket! (well, really big at least)
28         if capacity == -1:
29             capacity = 2**30 # 1 TeraByte capacity
30         self.capacity = float(capacity)
31         
32         self._tokens = float(0)
33         
34         self.fill_rate = float(fill_rate)
35         self.timestamp = time()
36
37     def consume(self, tokens):
38         """Consume tokens from the bucket. Returns True if there were
39         sufficient tokens otherwise False."""
40         if tokens <= self.tokens:
41             self._tokens -= tokens
42         else:
43             return False
44         return True
45     
46     def _consume_all(self):
47         """
48         Consumes every token in the bucket
49         """
50         self._tokens = float(0)
51
52     @property
53     def tokens(self):
54         if self._tokens < self.capacity:
55             now = time()
56             delta = self.fill_rate * (now - self.timestamp)
57             self._tokens = min(self.capacity, self._tokens + delta)
58             self.timestamp = now
59         return self._tokens
60     
61     @property
62     def upload_rate(self):
63         return self.fill_rate