| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef NET_NQE_OBSERVATION_BUFFER_H_ | 5 #ifndef NET_NQE_OBSERVATION_BUFFER_H_ |
| 6 #define NET_NQE_OBSERVATION_BUFFER_H_ | 6 #define NET_NQE_OBSERVATION_BUFFER_H_ |
| 7 | 7 |
| 8 #include <float.h> | 8 #include <float.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <deque> | 11 #include <deque> |
| 12 #include <memory> |
| 13 #include <utility> |
| 12 #include <vector> | 14 #include <vector> |
| 13 | 15 |
| 14 #include "base/gtest_prod_util.h" | |
| 15 #include "base/macros.h" | 16 #include "base/macros.h" |
| 17 #include "base/time/default_tick_clock.h" |
| 18 #include "base/time/tick_clock.h" |
| 16 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 17 #include "net/base/net_export.h" | 20 #include "net/base/net_export.h" |
| 21 #include "net/nqe/network_quality_observation.h" |
| 18 #include "net/nqe/network_quality_observation_source.h" | 22 #include "net/nqe/network_quality_observation_source.h" |
| 19 #include "net/nqe/weighted_observation.h" | 23 #include "net/nqe/weighted_observation.h" |
| 20 | 24 |
| 21 namespace net { | 25 namespace net { |
| 22 | 26 |
| 23 namespace nqe { | 27 namespace nqe { |
| 24 | 28 |
| 25 namespace internal { | 29 namespace internal { |
| 26 | 30 |
| 27 // Stores observations sorted by time. | 31 // Stores observations sorted by time. |
| 28 template <typename ValueType> | 32 template <typename ValueType> |
| 29 class NET_EXPORT_PRIVATE ObservationBuffer { | 33 class NET_EXPORT_PRIVATE ObservationBuffer { |
| 30 public: | 34 public: |
| 31 explicit ObservationBuffer(double weight_multiplier_per_second) | 35 explicit ObservationBuffer(double weight_multiplier_per_second) |
| 32 : weight_multiplier_per_second_(weight_multiplier_per_second) { | 36 : weight_multiplier_per_second_(weight_multiplier_per_second), |
| 37 tick_clock_(new base::DefaultTickClock()) { |
| 33 static_assert(kMaximumObservationsBufferSize > 0U, | 38 static_assert(kMaximumObservationsBufferSize > 0U, |
| 34 "Minimum size of observation buffer must be > 0"); | 39 "Minimum size of observation buffer must be > 0"); |
| 35 DCHECK_GE(weight_multiplier_per_second_, 0.0); | 40 DCHECK_GE(weight_multiplier_per_second_, 0.0); |
| 36 DCHECK_LE(weight_multiplier_per_second_, 1.0); | 41 DCHECK_LE(weight_multiplier_per_second_, 1.0); |
| 37 } | 42 } |
| 38 | 43 |
| 39 ~ObservationBuffer() {} | 44 ~ObservationBuffer() {} |
| 40 | 45 |
| 41 // Adds |observation| to the buffer. The oldest observation in the buffer | 46 // Adds |observation| to the buffer. The oldest observation in the buffer |
| 42 // will be evicted to make room if the buffer is already full. | 47 // will be evicted to make room if the buffer is already full. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 63 // Clears the observations stored in this buffer. | 68 // Clears the observations stored in this buffer. |
| 64 void Clear() { observations_.clear(); } | 69 void Clear() { observations_.clear(); } |
| 65 | 70 |
| 66 // Returns true iff the |percentile| value of the observations in this | 71 // Returns true iff the |percentile| value of the observations in this |
| 67 // buffer is available. Sets |result| to the computed |percentile| | 72 // buffer is available. Sets |result| to the computed |percentile| |
| 68 // value among all observations since |begin_timestamp|. If the value is | 73 // value among all observations since |begin_timestamp|. If the value is |
| 69 // unavailable, false is returned and |result| is not modified. Percentile | 74 // unavailable, false is returned and |result| is not modified. Percentile |
| 70 // value is unavailable if all the values in observation buffer are older | 75 // value is unavailable if all the values in observation buffer are older |
| 71 // than |begin_timestamp|. | 76 // than |begin_timestamp|. |
| 72 // |result| must not be null. | 77 // |result| must not be null. |
| 78 // TODO(tbansal): Move out param |result| as the last param of the function. |
| 73 bool GetPercentile(const base::TimeTicks& begin_timestamp, | 79 bool GetPercentile(const base::TimeTicks& begin_timestamp, |
| 74 ValueType* result, | 80 ValueType* result, |
| 75 int percentile, | 81 int percentile, |
| 76 const std::vector<NetworkQualityObservationSource>& | 82 const std::vector<NetworkQualityObservationSource>& |
| 77 disallowed_observation_sources) const { | 83 disallowed_observation_sources) const { |
| 78 DCHECK(result); | 84 DCHECK(result); |
| 79 DCHECK_GE(Capacity(), Size()); | 85 DCHECK_GE(Capacity(), Size()); |
| 80 // Stores WeightedObservation in increasing order of value. | 86 // Stores WeightedObservation in increasing order of value. |
| 81 std::vector<WeightedObservation<ValueType>> weighted_observations; | 87 std::vector<WeightedObservation<ValueType>> weighted_observations; |
| 82 | 88 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 109 | 115 |
| 110 // Computation may reach here due to floating point errors. This may happen | 116 // Computation may reach here due to floating point errors. This may happen |
| 111 // if |percentile| was 100 (or close to 100), and |desired_weight| was | 117 // if |percentile| was 100 (or close to 100), and |desired_weight| was |
| 112 // slightly larger than |total_weight| (due to floating point errors). | 118 // slightly larger than |total_weight| (due to floating point errors). |
| 113 // In this case, we return the highest |value| among all observations. | 119 // In this case, we return the highest |value| among all observations. |
| 114 // This is same as value of the last observation in the sorted vector. | 120 // This is same as value of the last observation in the sorted vector. |
| 115 *result = weighted_observations.at(weighted_observations.size() - 1).value; | 121 *result = weighted_observations.at(weighted_observations.size() - 1).value; |
| 116 return true; | 122 return true; |
| 117 } | 123 } |
| 118 | 124 |
| 125 void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock) { |
| 126 tick_clock_ = std::move(tick_clock); |
| 127 } |
| 128 |
| 119 private: | 129 private: |
| 120 // Maximum number of observations that can be held in the ObservationBuffer. | 130 // Maximum number of observations that can be held in the ObservationBuffer. |
| 121 static const size_t kMaximumObservationsBufferSize = 300; | 131 static const size_t kMaximumObservationsBufferSize = 300; |
| 122 | 132 |
| 123 // Computes the weighted observations and stores them in | 133 // Computes the weighted observations and stores them in |
| 124 // |weighted_observations| sorted by ascending |WeightedObservation.value|. | 134 // |weighted_observations| sorted by ascending |WeightedObservation.value|. |
| 125 // Only the observations with timestamp later than |begin_timestamp| are | 135 // Only the observations with timestamp later than |begin_timestamp| are |
| 126 // considered. Also, sets |total_weight| to the total weight of all | 136 // considered. Also, sets |total_weight| to the total weight of all |
| 127 // observations. Should be called only when there is at least one | 137 // observations. Should be called only when there is at least one |
| 128 // observation in the buffer. | 138 // observation in the buffer. |
| 129 void ComputeWeightedObservations( | 139 void ComputeWeightedObservations( |
| 130 const base::TimeTicks& begin_timestamp, | 140 const base::TimeTicks& begin_timestamp, |
| 131 std::vector<WeightedObservation<ValueType>>& weighted_observations, | 141 std::vector<WeightedObservation<ValueType>>& weighted_observations, |
| 132 double* total_weight, | 142 double* total_weight, |
| 133 const std::vector<NetworkQualityObservationSource>& | 143 const std::vector<NetworkQualityObservationSource>& |
| 134 disallowed_observation_sources) const { | 144 disallowed_observation_sources) const { |
| 135 DCHECK_GE(Capacity(), Size()); | 145 DCHECK_GE(Capacity(), Size()); |
| 136 | 146 |
| 137 weighted_observations.clear(); | 147 weighted_observations.clear(); |
| 138 double total_weight_observations = 0.0; | 148 double total_weight_observations = 0.0; |
| 139 base::TimeTicks now = base::TimeTicks::Now(); | 149 base::TimeTicks now = tick_clock_->NowTicks(); |
| 140 | 150 |
| 141 for (const auto& observation : observations_) { | 151 for (const auto& observation : observations_) { |
| 142 if (observation.timestamp < begin_timestamp) | 152 if (observation.timestamp < begin_timestamp) |
| 143 continue; | 153 continue; |
| 144 bool disallowed = false; | 154 bool disallowed = false; |
| 145 for (const auto& disallowed_source : disallowed_observation_sources) { | 155 for (const auto& disallowed_source : disallowed_observation_sources) { |
| 146 if (disallowed_source == observation.source) | 156 if (disallowed_source == observation.source) |
| 147 disallowed = true; | 157 disallowed = true; |
| 148 } | 158 } |
| 149 if (disallowed) | 159 if (disallowed) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 167 // front of the queue. | 177 // front of the queue. |
| 168 std::deque<Observation<ValueType>> observations_; | 178 std::deque<Observation<ValueType>> observations_; |
| 169 | 179 |
| 170 // The factor by which the weight of an observation reduces every second. | 180 // The factor by which the weight of an observation reduces every second. |
| 171 // For example, if an observation is 6 seconds old, its weight would be: | 181 // For example, if an observation is 6 seconds old, its weight would be: |
| 172 // weight_multiplier_per_second_ ^ 6 | 182 // weight_multiplier_per_second_ ^ 6 |
| 173 // Calculated from |kHalfLifeSeconds| by solving the following equation: | 183 // Calculated from |kHalfLifeSeconds| by solving the following equation: |
| 174 // weight_multiplier_per_second_ ^ kHalfLifeSeconds = 0.5 | 184 // weight_multiplier_per_second_ ^ kHalfLifeSeconds = 0.5 |
| 175 const double weight_multiplier_per_second_; | 185 const double weight_multiplier_per_second_; |
| 176 | 186 |
| 187 std::unique_ptr<base::TickClock> tick_clock_; |
| 188 |
| 177 DISALLOW_COPY_AND_ASSIGN(ObservationBuffer); | 189 DISALLOW_COPY_AND_ASSIGN(ObservationBuffer); |
| 178 }; | 190 }; |
| 179 | 191 |
| 180 } // namespace internal | 192 } // namespace internal |
| 181 | 193 |
| 182 } // namespace nqe | 194 } // namespace nqe |
| 183 | 195 |
| 184 } // namespace net | 196 } // namespace net |
| 185 | 197 |
| 186 #endif // NET_NQE_OBSERVATION_BUFFER_H_ | 198 #endif // NET_NQE_OBSERVATION_BUFFER_H_ |
| OLD | NEW |