~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/third_party/chromium/src/net/base/bandwidth_metrics.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (c) 2011 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
 
#ifndef NET_BASE_BANDWIDTH_METRICS_H_
6
 
#define NET_BASE_BANDWIDTH_METRICS_H_
7
 
 
8
 
#include <list>
9
 
 
10
 
#include "base/logging.h"
11
 
#include "base/metrics/histogram.h"
12
 
#include "base/time/time.h"
13
 
 
14
 
namespace net {
15
 
 
16
 
// Tracks statistics about the bandwidth metrics over time.  In order to
17
 
// measure, this class needs to know when individual streams are in progress,
18
 
// so that it can know when to discount idle time.  The BandwidthMetrics
19
 
// is unidirectional - it should only be used to record upload or download
20
 
// bandwidth, but not both.
21
 
//
22
 
// Note, the easiest thing to do is to just measure each stream and average
23
 
// them or add them.  However, this does not work.  If multiple streams are in
24
 
// progress concurrently, you have to look at the aggregate bandwidth at any
25
 
// point in time.
26
 
//
27
 
//   Example:
28
 
//      Imagine 4 streams opening and closing with overlapping time.
29
 
//      We can't measure bandwidth by looking at any individual stream.
30
 
//      We can only measure actual bandwidth by looking at the bandwidth
31
 
//      across all open streams.
32
 
//
33
 
//         Time --------------------------------------->
34
 
//         s1 +----------------+
35
 
//         s2              +----------------+
36
 
//         s3                            +--------------+
37
 
//         s4                            +--------------+
38
 
//
39
 
// Example usage:
40
 
//
41
 
//   BandwidthMetrics tracker;
42
 
//
43
 
//   // When a stream is created
44
 
//   tracker.StartStream();
45
 
//
46
 
//   // When data is transferred on any stream
47
 
//   tracker.RecordSample(bytes);
48
 
//
49
 
//   // When the stream is finished
50
 
//   tracker.StopStream();
51
 
//
52
 
// NOTE: This class is not thread safe.
53
 
//
54
 
class BandwidthMetrics {
55
 
 public:
56
 
  BandwidthMetrics()
57
 
      : num_streams_in_progress_(0),
58
 
        num_data_samples_(0),
59
 
        data_sum_(0.0),
60
 
        bytes_since_last_start_(0) {
61
 
  }
62
 
 
63
 
  // Get the bandwidth.  Returns Kbps (kilo-bits-per-second).
64
 
  double bandwidth() const {
65
 
    return data_sum_ / num_data_samples_;
66
 
  }
67
 
 
68
 
  // Record that we've started a stream.
69
 
  void StartStream() {
70
 
    // If we're the only stream, we've finished some idle time.  Record a new
71
 
    // timestamp to indicate the start of data flow.
72
 
    if (++num_streams_in_progress_ == 1) {
73
 
      last_start_ = base::TimeTicks::HighResNow();
74
 
      bytes_since_last_start_ = 0;
75
 
    }
76
 
  }
77
 
 
78
 
  // Track that we've completed a stream.
79
 
  void StopStream() {
80
 
    if (--num_streams_in_progress_ == 0) {
81
 
      // We don't use small streams when tracking bandwidth because they are not
82
 
      // precise; imagine a 25 byte stream.  The sample is too small to make
83
 
      // a good measurement.
84
 
      // 20KB is an arbitrary value.  We might want to use a lesser value.
85
 
      static const int64 kRecordSizeThreshold = 20 * 1024;
86
 
      if (bytes_since_last_start_ < kRecordSizeThreshold)
87
 
        return;
88
 
 
89
 
      base::TimeDelta delta = base::TimeTicks::HighResNow() - last_start_;
90
 
      double ms = delta.InMillisecondsF();
91
 
      if (ms > 0.0) {
92
 
        double kbps = static_cast<double>(bytes_since_last_start_) * 8 / ms;
93
 
        ++num_data_samples_;
94
 
        data_sum_ += kbps;
95
 
        VLOG(1) << "Bandwidth: " << kbps
96
 
                << "Kbps (avg " << bandwidth() << "Kbps)";
97
 
        int kbps_int = static_cast<int>(kbps);
98
 
        UMA_HISTOGRAM_COUNTS_10000("Net.DownloadBandwidth", kbps_int);
99
 
      }
100
 
    }
101
 
  }
102
 
 
103
 
  // Add a sample of the number of bytes read from the network into the tracker.
104
 
  void RecordBytes(int bytes) {
105
 
    DCHECK(num_streams_in_progress_);
106
 
    bytes_since_last_start_ += static_cast<int64>(bytes);
107
 
  }
108
 
 
109
 
 private:
110
 
  int num_streams_in_progress_;   // The number of streams in progress.
111
 
  // TODO(mbelshe): Use a rolling buffer of 30 samples instead of an average.
112
 
  int num_data_samples_;          // The number of samples collected.
113
 
  double data_sum_;               // The sum of all samples collected.
114
 
  int64 bytes_since_last_start_;  // Bytes tracked during this "session".
115
 
  base::TimeTicks last_start_;    // Timestamp of the begin of this "session".
116
 
};
117
 
 
118
 
// A utility class for managing the lifecycle of a measured stream.
119
 
// It is important that we not leave unclosed streams, and this class helps
120
 
// ensure we always stop them.
121
 
class ScopedBandwidthMetrics {
122
 
 public:
123
 
  ScopedBandwidthMetrics();
124
 
  ~ScopedBandwidthMetrics();
125
 
 
126
 
  void StartStream();
127
 
  void StopStream();
128
 
  void RecordBytes(int bytes);
129
 
 
130
 
 private:
131
 
  bool started_;
132
 
};
133
 
 
134
 
}  // namespace net
135
 
 
136
 
#endif  // NET_BASE_BANDWIDTH_METRICS_H_