-
Notifications
You must be signed in to change notification settings - Fork 36
/
memory-with-loss-signal.cc
119 lines (98 loc) · 4.21 KB
/
memory-with-loss-signal.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "memory-with-loss-signal.hh"
using namespace std;
static const double alpha = 1.0 / 8.0;
static const double slow_alpha = 1.0 / 256.0;
void Memory::packets_received( const vector< Packet > & packets, const unsigned int flow_id, const double link_rate_normalizing_factor )
{
for ( const auto &x : packets ) {
if ( x.flow_id != flow_id ) {
continue;
}
// Assumption: assuming no reordering to detect packet loss
if ( _largest_ack + 1 < x.seq_num ){
_lost_packets.push( x ); // WARNING: x is not the lost packet, but merely a representative. Bulk loss will not be detected this way
}
_largest_ack = max( _largest_ack, x.seq_num );
_all_packets_in_rtt_window.push( x );
const double rtt = x.tick_received - x.tick_sent;
if ( _last_tick_sent == 0 || _last_tick_received == 0 ) {
_last_tick_sent = x.tick_sent;
_last_tick_received = x.tick_received;
_last_receiver_timestamp = x.receiver_timestamp;
_min_rtt = rtt;
_rtt_estimate = rtt;
} else {
_rec_send_ewma = (1 - alpha) * _rec_send_ewma + alpha * (x.tick_sent - _last_tick_sent) * link_rate_normalizing_factor;
_rec_rec_ewma = (1 - alpha) * _rec_rec_ewma + alpha * (x.receiver_timestamp - _last_receiver_timestamp) * link_rate_normalizing_factor;
_slow_rec_rec_ewma = (1 - slow_alpha) * _slow_rec_rec_ewma + slow_alpha * (x.receiver_timestamp - _last_receiver_timestamp) * link_rate_normalizing_factor;
_last_tick_sent = x.tick_sent;
_last_tick_received = x.tick_received;
_last_receiver_timestamp = x.receiver_timestamp;
_min_rtt = min( _min_rtt, rtt );
_rtt_ratio = double( rtt ) / double( _min_rtt );
assert( _rtt_ratio >= 1.0 );
_rtt_estimate = (1 - alpha) * _rtt_estimate + alpha * rtt;
}
}
// pop all older packets
while( !_lost_packets.empty() && _lost_packets.front().tick_received < _last_tick_received - _rtt_estimate )
_lost_packets.pop();
while( !_all_packets_in_rtt_window.empty() && _all_packets_in_rtt_window.front().tick_received < _last_tick_received - _rtt_estimate)
_all_packets_in_rtt_window.pop();
//assert( _all_packets_in_rtt_window.size() >= _lost_packets.size() );
if ( _all_packets_in_rtt_window.empty() )
_loss_rate = 0;
else
_loss_rate = (( 0.1 * _lost_packets.size() ) / _all_packets_in_rtt_window.size()) * 163840;
}
string Memory::str( void ) const
{
char tmp[ 256 ];
snprintf( tmp, 256, "sewma=%f, rewma=%f, rttr=%f, lossrt=%f", _rec_send_ewma, _rec_rec_ewma, _rtt_ratio, _loss_rate);
return tmp;
}
const Memory & MAX_MEMORY( void )
{
static const Memory max_memory( { 163840, 163840, 163840, 163840 } );
return max_memory;
}
RemyBuffers::Memory Memory::DNA( void ) const
{
RemyBuffers::Memory ret;
ret.set_rec_send_ewma( _rec_send_ewma );
ret.set_rec_rec_ewma( _rec_rec_ewma );
ret.set_rtt_ratio( _rtt_ratio );
//ret.set_slow_rec_rec_ewma( _slow_rec_rec_ewma );
ret.set_loss_rate( _loss_rate );
return ret;
}
/* If fields are missing in the DNA, we want to wildcard the resulting rule to match anything */
#define get_val_or_default( protobuf, field, limit ) \
( (protobuf).has_ ## field() ? (protobuf).field() : (limit) ? 0 : 163840 )
Memory::Memory( const bool is_lower_limit, const RemyBuffers::Memory & dna )
: _rec_send_ewma( get_val_or_default( dna, rec_send_ewma, is_lower_limit ) ),
_rec_rec_ewma( get_val_or_default( dna, rec_rec_ewma, is_lower_limit ) ),
_rtt_ratio( get_val_or_default( dna, rtt_ratio, is_lower_limit ) ),
//_slow_rec_rec_ewma( get_val_or_default( dna, slow_rec_rec_ewma, is_lower_limit ) ),
_slow_rec_rec_ewma( 0 ),
_loss_rate( get_val_or_default( dna, loss_rate, is_lower_limit ) ),
_last_tick_sent( 0 ),
_last_tick_received( 0 ),
_last_receiver_timestamp( 0 ),
_min_rtt( 0 ),
_rtt_estimate( 0 ),
_lost_packets( ),
_all_packets_in_rtt_window( ),
_largest_ack( 0 )
{
}
size_t hash_value( const Memory & mem )
{
size_t seed = 0;
boost::hash_combine( seed, mem._rec_send_ewma );
boost::hash_combine( seed, mem._rec_rec_ewma );
boost::hash_combine( seed, mem._rtt_ratio );
//boost::hash_combine( seed, mem._slow_rec_rec_ewma );
boost::hash_combine( seed, mem._loss_rate);
return seed;
}