observation_buffer.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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
  3. // found in the LICENSE file.
  4. #ifndef NET_NQE_OBSERVATION_BUFFER_H_
  5. #define NET_NQE_OBSERVATION_BUFFER_H_
  6. #include <stdint.h>
  7. #include <map>
  8. #include <memory>
  9. #include <set>
  10. #include <vector>
  11. #include "base/containers/circular_deque.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/time/tick_clock.h"
  14. #include "net/base/net_export.h"
  15. #include "net/nqe/network_quality_estimator_util.h"
  16. #include "net/nqe/network_quality_observation.h"
  17. #include "net/nqe/network_quality_observation_source.h"
  18. #include "third_party/abseil-cpp/absl/types/optional.h"
  19. namespace base {
  20. class TimeTicks;
  21. } // namespace base
  22. namespace net {
  23. class NetworkQualityEstimatorParams;
  24. namespace nqe::internal {
  25. struct WeightedObservation;
  26. // Stores observations sorted by time and provides utility functions for
  27. // computing weighted and non-weighted summary statistics.
  28. class NET_EXPORT_PRIVATE ObservationBuffer {
  29. public:
  30. ObservationBuffer(const NetworkQualityEstimatorParams* params,
  31. const base::TickClock* tick_clock,
  32. double weight_multiplier_per_second,
  33. double weight_multiplier_per_signal_level);
  34. // This constructor does not copy the |observations_| from |other| to |this|.
  35. // As such, this constructor should only be called before adding any
  36. // observations to |other|.
  37. ObservationBuffer(const ObservationBuffer& other);
  38. ObservationBuffer& operator=(const ObservationBuffer&) = delete;
  39. ~ObservationBuffer();
  40. // Adds |observation| to the buffer. The oldest observation in the buffer
  41. // will be evicted to make room if the buffer is already full.
  42. void AddObservation(const Observation& observation);
  43. // Returns the number of observations in this buffer.
  44. size_t Size() const { return static_cast<size_t>(observations_.size()); }
  45. // Returns the capacity of this buffer.
  46. size_t Capacity() const;
  47. // Clears the observations stored in this buffer.
  48. void Clear() { observations_.clear(); }
  49. // Returns true iff the |percentile| value of the observations in this
  50. // buffer is available. Sets |result| to the computed |percentile|
  51. // value of all observations made on or after |begin_timestamp|. If the
  52. // value is unavailable, false is returned and |result| is not modified.
  53. // Percentile value is unavailable if all the values in observation buffer are
  54. // older than |begin_timestamp|. |current_signal_strength| is the current
  55. // signal strength. |result| must not be null. If |observations_count| is not
  56. // null, then it is set to the number of observations that were available
  57. // in the observation buffer for computing the percentile.
  58. absl::optional<int32_t> GetPercentile(base::TimeTicks begin_timestamp,
  59. int32_t current_signal_strength,
  60. int percentile,
  61. size_t* observations_count) const;
  62. void SetTickClockForTesting(const base::TickClock* tick_clock) {
  63. tick_clock_ = tick_clock;
  64. }
  65. // Removes all observations from the buffer whose corresponding entry in
  66. // |deleted_observation_sources| is set to true. For example, if index 1 and
  67. // 3 in |deleted_observation_sources| are set to true, then all observations
  68. // in the buffer that have source set to either 1 or 3 would be removed.
  69. void RemoveObservationsWithSource(
  70. bool deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_MAX]);
  71. private:
  72. // Computes the weighted observations and stores them in
  73. // |weighted_observations| sorted by ascending |WeightedObservation.value|.
  74. // Only the observations with timestamp later than |begin_timestamp| are
  75. // considered. |current_signal_strength| is the current signal strength
  76. // when the observation was taken. This method also sets |total_weight| to
  77. // the total weight of all observations. Should be called only when there is
  78. // at least one observation in the buffer.
  79. void ComputeWeightedObservations(
  80. const base::TimeTicks& begin_timestamp,
  81. int32_t current_signal_strength,
  82. std::vector<WeightedObservation>* weighted_observations,
  83. double* total_weight) const;
  84. raw_ptr<const NetworkQualityEstimatorParams> params_;
  85. // Holds observations sorted by time, with the oldest observation at the
  86. // front of the queue.
  87. base::circular_deque<Observation> observations_;
  88. // The factor by which the weight of an observation reduces every second.
  89. // For example, if an observation is 6 seconds old, its weight would be:
  90. // weight_multiplier_per_second_ ^ 6
  91. // Calculated from |kHalfLifeSeconds| by solving the following equation:
  92. // weight_multiplier_per_second_ ^ kHalfLifeSeconds = 0.5
  93. const double weight_multiplier_per_second_;
  94. // The factor by which the weight of an observation reduces for every unit
  95. // difference in the current signal strength, and the signal strength at
  96. // which the observation was taken.
  97. // For example, if the observation was taken at 1 unit, and current signal
  98. // strength is 4 units, the weight of the observation would be:
  99. // |weight_multiplier_per_signal_level_| ^ 3.
  100. const double weight_multiplier_per_signal_level_;
  101. raw_ptr<const base::TickClock> tick_clock_;
  102. };
  103. } // namespace nqe::internal
  104. } // namespace net
  105. #endif // NET_NQE_OBSERVATION_BUFFER_H_