summaryrefslogtreecommitdiffstats
path: root/libktorrent/torrent/upspeedestimater.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libktorrent/torrent/upspeedestimater.cpp')
-rw-r--r--libktorrent/torrent/upspeedestimater.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/libktorrent/torrent/upspeedestimater.cpp b/libktorrent/torrent/upspeedestimater.cpp
new file mode 100644
index 0000000..0d6c544
--- /dev/null
+++ b/libktorrent/torrent/upspeedestimater.cpp
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <math.h>
+#include <util/functions.h>
+#include <util/log.h>
+#include <torrent/globals.h>
+#include "upspeedestimater.h"
+
+namespace bt
+{
+
+ UpSpeedEstimater::UpSpeedEstimater()
+ {
+ accumulated_bytes = 0;
+ upload_rate = 0.0;
+ proto_upload_rate = 0.0;
+ }
+
+
+ UpSpeedEstimater::~UpSpeedEstimater()
+ {}
+
+
+ void UpSpeedEstimater::writeBytes(Uint32 bytes,bool proto)
+ {
+ // add entry to outstanding_bytes
+ Entry e;
+ e.bytes = bytes;
+ e.data = !proto;
+ e.start_time = GetCurrentTime();
+ outstanding_bytes.append(e);
+ }
+
+ void UpSpeedEstimater::bytesWritten(Uint32 bytes)
+ {
+ QValueList<Entry>::iterator i = outstanding_bytes.begin();
+ TimeStamp now = GetCurrentTime();
+ while (bytes > 0 && i != outstanding_bytes.end())
+ {
+ Entry e = *i;
+ if (e.bytes <= bytes + accumulated_bytes)
+ {
+ // first remove outstanding bytes
+ i = outstanding_bytes.erase(i);
+ bytes -= e.bytes;
+ accumulated_bytes = 0;
+ if (e.data)
+ {
+ // if it's data move it to the written_bytes list
+ // but first store time it takes to send in e.t
+ e.duration = now - e.start_time;
+ written_bytes.append(e);
+ }
+ else
+ {
+ e.duration = now - e.start_time;
+#ifdef MEASURE_PROTO_OVERHEAD
+ proto_bytes.append(e);
+#endif
+ }
+ }
+ else
+ {
+ accumulated_bytes += bytes;
+ bytes = 0;
+ }
+ }
+ }
+
+ double UpSpeedEstimater::rate(QValueList<Entry> & el)
+ {
+ TimeStamp now = GetCurrentTime();
+ const Uint32 INTERVAL = 3000;
+
+ Uint32 tot_bytes = 0;
+ Uint32 oldest_time = now;
+
+ QValueList<Entry>::iterator i = el.begin();
+ while (i != el.end())
+ {
+ Entry & e = *i;
+ Uint32 end_time = e.start_time + e.duration;
+
+ if (now - end_time > INTERVAL)
+ {
+ // get rid of old entries
+ i = el.erase(i);
+ }
+ else if (now - e.start_time <= INTERVAL)
+ {
+ // entry was fully sent in the last 3 seconds
+ // so fully add it
+ tot_bytes += e.bytes;
+ if (e.start_time < oldest_time)
+ oldest_time = e.start_time;
+ i++;
+ }
+ else
+ {
+ // entry was partially sent in the last 3 seconds
+ // so we need to take into account a part of the bytes;
+ Uint32 part_dur = end_time - (now - INTERVAL);
+ double dur_perc = (double)part_dur / e.duration;
+ tot_bytes += (Uint32)ceil(dur_perc * e.bytes);
+ oldest_time = (now - INTERVAL);
+ i++;
+ }
+ }
+
+ return (double)tot_bytes / (INTERVAL * 0.001);
+ }
+
+ void UpSpeedEstimater::update()
+ {
+ if (!written_bytes.empty())
+ {
+ upload_rate = 0;
+ upload_rate = rate(written_bytes);
+ }
+
+
+#ifdef MEASURE_PROTO_OVERHEAD
+ if (!proto_bytes.empty())
+ {
+ proto_upload_rate = 0;
+ proto_upload_rate = rate(proto_bytes);
+ }
+#endif
+ }
+
+}