Skip to content

Commit 0aa834f

Browse files
committed
fixed proper accumulation of values, handlign both missing and duplicate records
1 parent 4c7a8d1 commit 0aa834f

5 files changed

Lines changed: 143 additions & 17 deletions

File tree

retroshare-gui/src/gui/statistics/BWGraph.cpp

Lines changed: 118 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,96 @@ void BWGraphSource::update()
4141
std::cerr << " got " << std::dec << thc.in_rstcl.size() << " in clues" << std::endl;
4242
#endif
4343

44-
// keep track of them, in case we need to change the sorting
44+
// This does two important things:
45+
// 1 - look into the previous record and add the missing ones to the current record with cumulated sizes only, in order to
46+
// remove gaps in the traffic clues history when some elements are not present.
47+
// 2 - if the received data contains duplicates, zero the cumulative data of all similar elements except one which is set to the max
48+
// so that they can be added without creating errors when e.g. adding all elements of the same service.
49+
50+
auto add_missing_elements = [](std::list<RSTrafficClue>& existing_lst,const std::list<RSTrafficClue>& to_add) {
51+
52+
auto some_hash_function = [](const RSTrafficClue& tc) -> uint64_t {
53+
return tc.peer_id.toByteArray()[0]+(tc.peer_id.toByteArray()[1] << 8) + (tc.peer_id.toByteArray()[2] << 16)
54+
+ (tc.peer_id.toByteArray()[3] << 24) + ((uint64_t)tc.service_id << 32) + ((uint64_t)tc.service_sub_id << 48);
55+
};
56+
// map containing for each (service_id,service_sub_id,peer) the total and max cumulated size and cumulated count so far.
57+
58+
struct MaxRecord {
59+
uint64_t max_cumulated_size;
60+
uint64_t max_cumulated_count;
61+
62+
MaxRecord() : max_cumulated_size(0),max_cumulated_count(0){}
63+
};
64+
65+
std::map<uint64_t,MaxRecord> present;
66+
uint64_t ts = existing_lst.empty()?0:existing_lst.front().TS;
67+
68+
auto correct_max_total = [](uint64_t& proposed_value,uint64_t& maximum_so_far) {
69+
uint64_t mx = std::max(proposed_value,maximum_so_far);
70+
71+
if(proposed_value <= mx)
72+
proposed_value = 0;
73+
else
74+
{
75+
proposed_value -= maximum_so_far;
76+
maximum_so_far = mx;
77+
}
78+
};
79+
80+
for(auto& c:existing_lst)
81+
{
82+
std::cerr << "inserting element with hash " << some_hash_function(c) << " peer=" << c.peer_id << " service " << c.service_id
83+
<< " (" << (int)c.service_sub_id << ")" << std::endl;
4584

85+
uint64_t hash = some_hash_function(c);
86+
auto it = present.find(hash);
87+
88+
if(it != present.end())
89+
{
90+
// One record is already there. So we prevent the duplicate count of cumulated values by making sure
91+
// that it->second + c = max(it->second,c)
92+
93+
correct_max_total(c.cumulated_size,it->second.max_cumulated_size);
94+
correct_max_total(c.cumulated_count,it->second.max_cumulated_count);
95+
}
96+
else
97+
{
98+
MaxRecord mx;
99+
mx.max_cumulated_size = c.cumulated_size;
100+
mx.max_cumulated_count = c.cumulated_count;
101+
present[hash] = mx;
102+
}
103+
}
104+
105+
for(const auto& x:to_add)
106+
if(present.find(some_hash_function(x)) == present.end()) // each missing element is added only once
107+
{
108+
auto x_cpy(x);
109+
x_cpy.size = 0;
110+
x_cpy.count = 0;
111+
x_cpy.TS = ts;
112+
113+
std::cerr << "Adding new element with hash " << some_hash_function(x) << " peer=" << x.peer_id << " service " << x.service_id
114+
<< " (" << (int)x.service_sub_id << ")" << std::endl;
115+
existing_lst.push_back(x_cpy);
116+
present[some_hash_function(x)] = MaxRecord(); // we dont' care for values here.
117+
}
118+
};
46119
thc.time_stamp = getTime() ;
120+
121+
if(!mTrafficHistory.empty())
122+
{
123+
add_missing_elements(thc.out_rstcl,mTrafficHistory.back().out_rstcl);
124+
// add_missing_elements(thc.in_rstcl ,mTrafficHistory.back().in_rstcl);
125+
}
126+
127+
std::cerr << "Traffic detail:" << std::endl;
128+
for(const auto& tc:thc.out_rstcl)
129+
std::cerr << "TS=" << tc.TS << " peer=" << tc.peer_id << " service " << tc.service_id << " ("
130+
<< (int)tc.service_sub_id << ") " << tc.size << " ( " << tc.cumulated_size << ")" << tc.count << " ( " << tc.cumulated_count << ")"<< std::endl;
131+
132+
// keep track of them, in case we need to change the sorting
133+
47134
mTrafficHistory.push_back(thc) ;
48135

49136
std::set<RsPeerId> fds ;
@@ -200,6 +287,19 @@ void BWGraphSource::update()
200287
#endif
201288
}
202289

290+
void BWGraphSource::clear()
291+
{
292+
_total_sent =0;
293+
_total_recv =0;
294+
295+
_total_duration_seconds =0;
296+
297+
mTrafficHistory.clear() ;
298+
299+
mVisibleFriends.clear() ;
300+
mVisibleServices.clear() ;
301+
302+
}
203303
void BWGraphSource::getCumulatedValues(std::vector<float>& vals) const
204304
{
205305
if(_current_unit == UNIT_KILOBYTES && _total_duration_seconds > 0.0)
@@ -244,23 +344,23 @@ void BWGraphSource::convertTrafficClueToValues(const std::list<RSTrafficClue>& l
244344
{
245345
std::vector<RSTrafficClue> clue_per_sub_id(256) ;
246346

247-
for(std::list<RSTrafficClue>::const_iterator it(lst.begin());it!=lst.end();++it)
248-
if(it->peer_id == _current_selected_friend && it->service_id == _current_selected_service)
249-
clue_per_sub_id[it->service_sub_id] += *it ;
347+
for(std::list<RSTrafficClue>::const_iterator it(lst.begin());it!=lst.end();++it)
348+
if(it->peer_id == _current_selected_friend && it->service_id == _current_selected_service)
349+
clue_per_sub_id[it->service_sub_id] += *it ;
250350

251-
for(uint32_t i=0;i<256;++i)
252-
if(clue_per_sub_id[i].count > 0)
351+
for(uint32_t i=0;i<256;++i)
352+
if(clue_per_sub_id[i].cumulated_count > 0) // checks if i corresponds to an active service
253353
vals[makeSubItemName(clue_per_sub_id[i].service_id,i)] = select_value(clue_per_sub_id[i]);
254-
}
354+
}
255355
break ;
256356

257357
case GRAPH_TYPE_ALL: // single friend, all services => one curve per service id
258358
{
259359
std::map<uint16_t,RSTrafficClue> clue_per_id ;
260360

261-
for(std::list<RSTrafficClue>::const_iterator it(lst.begin());it!=lst.end();++it)
262-
if(it->peer_id == _current_selected_friend)
263-
clue_per_id[it->service_id] += *it ;
361+
for(std::list<RSTrafficClue>::const_iterator it(lst.begin());it!=lst.end();++it)
362+
if(it->peer_id == _current_selected_friend)
363+
clue_per_id[it->service_id] += *it ;
264364

265365
for(std::map<uint16_t,RSTrafficClue>::const_iterator it(clue_per_id.begin());it!=clue_per_id.end();++it)
266366
vals[mServiceInfoMap[it->first].mServiceName] = select_value(it->second);
@@ -271,9 +371,9 @@ void BWGraphSource::convertTrafficClueToValues(const std::list<RSTrafficClue>& l
271371
RSTrafficClue total ;
272372
std::map<uint16_t,RSTrafficClue> clue_per_id ;
273373

274-
for(std::list<RSTrafficClue>::const_iterator it(lst.begin());it!=lst.end();++it)
275-
if(it->peer_id == _current_selected_friend)
276-
total += *it ;
374+
for(std::list<RSTrafficClue>::const_iterator it(lst.begin());it!=lst.end();++it)
375+
if(it->peer_id == _current_selected_friend)
376+
total += *it ;
277377

278378
vals[visibleFriendName(_current_selected_friend)] = select_value(total);
279379
}
@@ -328,7 +428,7 @@ void BWGraphSource::convertTrafficClueToValues(const std::list<RSTrafficClue>& l
328428
}
329429

330430
for(uint32_t i=0;i<256;++i)
331-
if(clue_per_sub_id[i].count > 0)
431+
if(clue_per_sub_id[i].cumulated_count > 0) // checks if this corresponds to an active service
332432
vals[makeSubItemName(clue_per_sub_id[i].service_id,i)] = select_value(clue_per_sub_id[i]);
333433
}
334434
break ;
@@ -353,6 +453,8 @@ void BWGraphSource::convertTrafficClueToValues(const std::list<RSTrafficClue>& l
353453
total += *it;
354454

355455
vals[QString("Total").toStdString()] = select_value(total);
456+
std::cerr << "Total is " << total << std::endl;
457+
std::cerr << "Value is " << select_value(total) << std::endl;
356458
}
357459
break ;
358460
}
@@ -555,6 +657,7 @@ void BWGraphSource::setDirection(int dir)
555657

556658
void BWGraphSource::setTiming(int t)
557659
{
660+
std::cerr << "BWGraphSource: updating" << std::endl;
558661
if(t == _current_timing)
559662
return;
560663

@@ -563,7 +666,7 @@ void BWGraphSource::setTiming(int t)
563666
}
564667
void BWGraphSource::recomputeCurrentCurves()
565668
{
566-
#ifdef BWGRAPH_DEBUG
669+
#ifndef BWGRAPH_DEBUG
567670
std::cerr << "BWGraphSource: recomputing current curves." << std::endl;
568671
#endif
569672

retroshare-gui/src/gui/statistics/BWGraph.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ class BWGraphSource: public RSGraphSource
3333
std::list<RSTrafficClue> out_rstcl ;
3434
std::list<RSTrafficClue> in_rstcl ;
3535
};
36+
struct CumulatedStat
37+
{
38+
CumulatedStat() : cumulated_size(0),cumulated_count(0) {}
39+
uint64_t cumulated_size;
40+
uint64_t cumulated_count;
41+
};
42+
3643
class RsServiceInfoWithNames: public RsServiceInfo
3744
{
3845
public:
@@ -75,6 +82,7 @@ class BWGraphSource: public RSGraphSource
7582
const std::map<RsPeerId,std::string>& visibleFriends() const { return mVisibleFriends; }
7683
const std::set<uint16_t>& visibleServices() const { return mVisibleServices; }
7784

85+
void clear();
7886
protected:
7987
void convertTrafficClueToValues(const std::list<RSTrafficClue> &lst, std::map<std::string, float> &vals) const;
8088
std::string makeSubItemName(uint16_t service_id,uint8_t sub_item_type) const;
@@ -116,6 +124,7 @@ class BWGraph: public RSGraphWidget
116124
void setDirection(int dir) { _local_source->setDirection(dir); }
117125
void setTiming(int t) { _local_source->setTiming(t); }
118126
void setUnit(int unit) { _local_source->setUnit(unit) ;}
127+
void clear() { _local_source->clear() ; }
119128

120129
int direction() const { return _local_source->direction(); }
121130

retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent)
6363
QObject::connect(ui.updn_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateUpDownSelection(int ))) ;
6464
QObject::connect(ui.timing_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateTimingSelection(int ))) ;
6565
QObject::connect(ui.unit_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateUnitSelection(int ))) ;
66+
QObject::connect(ui.clear_PB ,SIGNAL( clicked( )),this, SLOT( clearHistory( ))) ;
6667
QObject::connect(ui.service_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT(updateServiceSelection(int ))) ;
6768
QObject::connect(ui.legend_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateLegendType(int ))) ;
6869
QObject::connect(ui.logScale_CB,SIGNAL( toggled(bool)),this, SLOT( toggleLogScale(bool))) ;
@@ -92,6 +93,10 @@ BandwidthStatsWidget::~BandwidthStatsWidget ()
9293
processSettings(false);
9394
}
9495

96+
void BandwidthStatsWidget::clearHistory()
97+
{
98+
ui.bwgraph_BW->clear();
99+
}
95100
void BandwidthStatsWidget::processSettings(bool bLoad)
96101
{
97102
m_bProcessSettings = true;
@@ -258,6 +263,7 @@ void BandwidthStatsWidget::updateServiceSelection(int n)
258263

259264
void BandwidthStatsWidget::updateTimingSelection(int n)
260265
{
266+
std::cerr << "updating timing to " << n << " !" << std::endl;
261267
if(n==0)
262268
ui.bwgraph_BW->setTiming(BWGraphSource::TIMING_INSTANT) ;
263269
else

retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ protected slots:
4343
void updateLegendType(int n);
4444
void updateGraphSelection(int n);
4545
void updateTimingSelection(int n);
46+
void clearHistory();
4647

4748
private:
4849
void processSettings(bool bLoad);

retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>900</width>
9+
<width>1072</width>
1010
<height>385</height>
1111
</rect>
1212
</property>
@@ -146,7 +146,7 @@
146146
</widget>
147147
</item>
148148
<item>
149-
<widget class="QComboBox" name="timing_CB">
149+
<widget class="RSComboBox" name="timing_CB">
150150
<item>
151151
<property name="text">
152152
<string>Instant</string>
@@ -180,6 +180,13 @@
180180
</item>
181181
</widget>
182182
</item>
183+
<item>
184+
<widget class="QPushButton" name="clear_PB">
185+
<property name="text">
186+
<string>Clear</string>
187+
</property>
188+
</widget>
189+
</item>
183190
<item>
184191
<spacer name="horizontalSpacer">
185192
<property name="orientation">

0 commit comments

Comments
 (0)