Blob Blame History Raw
From 1911decab746ad8046d00768f6125c7a98ed4fd3 Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <praiskup@redhat.com>
Date: Mon, 18 Jan 2016 18:32:20 +0100
Subject: [PATCH 1/2] (possibly) enlarge dequeue() to give us better statistics

It happened on Fedora 23 x86_64 that if the next() was called with
constant window of n=8196 units (in Bytes, default with
MultipartEncoderMonitor) -- some cache/buffer on the road caused
that the sum of deltas started to be highly inaccurate (bar shown
like 40MB instead of 1MB _most_ of the time).  This could be
solved by higher sma_window;  but we would have to rather large
numbers there and that would result in high complexity.

So store into deque() also "actual" time() and count all units in
window in separate variable (self._in_window) to avoid sum()
complexity issues.  That way we may count:

    (actual_time - last_item_time) / items_in_window

This would allow us to raise the value of sma_window.

This resolves verigak/progress/pull/24.
---
 progress/__init__.py | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/progress/__init__.py b/progress/__init__.py
index a860e2c..3130fe1 100644
--- a/progress/__init__.py
+++ b/progress/__init__.py
@@ -32,7 +32,8 @@ class Infinite(object):
         self.index = 0
         self.start_ts = time()
         self._ts = self.start_ts
-        self._dt = deque(maxlen=self.sma_window)
+        self._dt = deque()
+        self._in_window = 0
         for key, val in kwargs.items():
             setattr(self, key, val)
 
@@ -43,7 +44,9 @@ class Infinite(object):
 
     @property
     def avg(self):
-        return sum(self._dt) / len(self._dt) if self._dt else 0
+        if not self._in_window:
+            return 0
+        return (self._ts - self._dt[0]['t']) / self._in_window
 
     @property
     def elapsed(self):
@@ -63,11 +66,13 @@ class Infinite(object):
         pass
 
     def next(self, n=1):
-        if n > 0:
-            now = time()
-            dt = (now - self._ts) / n
-            self._dt.append(dt)
-            self._ts = now
+        self._ts = time()
+        self._dt.append({'t': self._ts, 'n': n})
+        self._in_window = self._in_window + n
+
+        if len(self._dt) > self.sma_window:
+            item = self._dt.popleft()
+            self._in_window = self._in_window - item['n']
 
         self.index = self.index + n
         self.update()
-- 
2.7.4