TimeLeftEstimator.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. # The contents of this file are subject to the BitTorrent Open Source License
  2. # Version 1.1 (the License). You may not copy or use this file, in either
  3. # source code or executable form, except in compliance with the License. You
  4. # may obtain a copy of the License at http://www.bittorrent.com/license/.
  5. #
  6. # Software distributed under the License is distributed on an AS IS basis,
  7. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  8. # for the specific language governing rights and limitations under the
  9. # License.
  10. # Written by Bram Cohen
  11. from BTL.platform import bttime
  12. class TimeLeftEstimator(object):
  13. def __init__(self, left):
  14. self.start = None
  15. self.last = None
  16. self.rate = 0
  17. self.remaining = None
  18. self.left = left
  19. self.broke = False
  20. self.got_anything = False
  21. self.when_next_expected = bttime() + 5
  22. def add_amount(self, amount):
  23. """ add number of bytes received """
  24. if not self.got_anything:
  25. self.got_anything = True
  26. self.start = bttime() - 2
  27. self.last = self.start
  28. self.left -= amount
  29. return
  30. self.update(bttime(), amount)
  31. def remove_amount(self, amount):
  32. self.left += amount
  33. def get_time_left(self):
  34. """ returns seconds """
  35. if not self.got_anything:
  36. return None
  37. t = bttime()
  38. if t - self.last > 15:
  39. self.update(t, 0)
  40. return self.remaining
  41. def get_size_left(self):
  42. return self.left
  43. def update(self, t, amount):
  44. self.left -= amount
  45. if t < self.when_next_expected and amount == 0:
  46. return
  47. try:
  48. self.rate = ((self.rate * (self.last - self.start)) + amount) / (t - self.start)
  49. self.last = t
  50. self.remaining = self.left / self.rate
  51. if self.start < self.last - self.remaining:
  52. self.start = self.last - self.remaining
  53. except ZeroDivisionError:
  54. self.remaining = None
  55. if self.broke and self.last - self.start < 20:
  56. self.start = self.last - 20
  57. if self.last - self.start > 20:
  58. self.broke = True
  59. self.when_next_expected = t + min((amount / max(self.rate, 0.0001)), 5)