Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / net / quic / congestion_control / inter_arrival_probe.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/congestion_control/inter_arrival_probe.h"
6
7 #include <algorithm>
8
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11
12 using std::max;
13
14 namespace net {
15
16 namespace {
17 const int kProbeSizePackets = 10;
18 const QuicByteCount kMinPacketSize = 500;
19 const int64 kDefaultBytesPerSecond = 40000;
20 const float kUncertainScaleFactor = 0.5;  // TODO(pwestin): revisit this factor.
21 }
22
23 InterArrivalProbe::InterArrivalProbe(QuicByteCount max_segment_size)
24     : max_segment_size_(max_segment_size),
25       estimate_available_(false),
26       available_channel_estimate_(QuicBandwidth::Zero()),
27       unacked_data_(0) {
28 }
29
30 InterArrivalProbe::~InterArrivalProbe() {
31 }
32
33 bool InterArrivalProbe::GetEstimate(QuicBandwidth* available_channel_estimate) {
34   if (!estimate_available_) {
35     return false;
36   }
37   *available_channel_estimate = available_channel_estimate_;
38   return true;
39 }
40
41 void InterArrivalProbe::OnPacketSent(QuicByteCount bytes) {
42   if (!estimate_available_) {
43     unacked_data_ += bytes;
44   }
45 }
46
47 void InterArrivalProbe::OnAcknowledgedPacket(QuicByteCount bytes) {
48   if (!estimate_available_) {
49     DCHECK_LE(bytes, unacked_data_);
50     unacked_data_ -= bytes;
51   }
52 }
53
54 void InterArrivalProbe::OnRetransmissionTimeout() {
55   if (!estimate_available_) {
56     unacked_data_ = 0;
57   }
58 }
59
60 QuicByteCount InterArrivalProbe::GetAvailableCongestionWindow() {
61   if (estimate_available_) {
62     return 0;
63   }
64   return (kProbeSizePackets * max_segment_size_) - unacked_data_;
65 }
66
67 void InterArrivalProbe::OnIncomingFeedback(
68     QuicPacketSequenceNumber sequence_number,
69     QuicByteCount bytes_sent,
70     QuicTime time_sent,
71     QuicTime time_received) {
72   if (estimate_available_) {
73     return;
74   }
75
76   if (available_channel_estimator_.get() == NULL) {
77     if (bytes_sent < kMinPacketSize) {
78       // Packet too small to start the probe phase.
79       return;
80     }
81     first_sequence_number_ = sequence_number;
82     available_channel_estimator_.reset(new AvailableChannelEstimator(
83         sequence_number, time_sent, time_received));
84     return;
85   }
86
87   available_channel_estimator_->OnIncomingFeedback(sequence_number,
88                                                    bytes_sent,
89                                                    time_sent,
90                                                    time_received);
91   if (sequence_number < kProbeSizePackets - 1  + first_sequence_number_) {
92     // We need more feedback before we have a probe estimate.
93     return;
94   }
95   // Get the current estimated available channel capacity.
96   // available_channel_estimate is invalid if kAvailableChannelEstimateUnknown
97   // is returned.
98   QuicBandwidth available_channel_estimate = QuicBandwidth::Zero();
99   AvailableChannelEstimateState available_channel_estimate_state =
100       available_channel_estimator_->GetAvailableChannelEstimate(
101           &available_channel_estimate);
102   switch (available_channel_estimate_state) {
103     case kAvailableChannelEstimateUnknown:
104       // Backup when we miss our probe.
105       available_channel_estimate_ =
106           QuicBandwidth::FromBytesPerSecond(kDefaultBytesPerSecond);
107       break;
108     case kAvailableChannelEstimateUncertain:
109       available_channel_estimate_ =
110           available_channel_estimate.Scale(kUncertainScaleFactor);
111       break;
112     case kAvailableChannelEstimateGood:
113       available_channel_estimate_ = available_channel_estimate;
114       break;
115     case kAvailableChannelEstimateSenderLimited:
116       available_channel_estimate_ =
117           max(available_channel_estimate,
118               QuicBandwidth::FromBytesPerSecond(kDefaultBytesPerSecond));
119       break;
120   }
121   estimate_available_ = true;
122   available_channel_estimator_.reset(NULL);
123   DVLOG(1) << "Probe estimate:"
124              << available_channel_estimate_.ToKBitsPerSecond()
125              << " Kbits/s";
126 }
127
128 }  // namespace net