1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef THRIFT_TEST_LOADGEN_LATENCYSCOREBOARD_H_
18 #define THRIFT_TEST_LOADGEN_LATENCYSCOREBOARD_H_ 1
19 
20 #include <folly/stats/Histogram.h>
21 
22 #include <thrift/lib/cpp/test/loadgen/ScoreBoard.h>
23 #include <thrift/lib/cpp/test/loadgen/ScoreBoardOpVector.h>
24 
25 #include <chrono>
26 
27 namespace apache {
28 namespace thrift {
29 namespace loadgen {
30 
31 /**
32  * A ScoreBoard that tracks number of queries per second, as well as
33  * information about how long each operation takes.
34  *
35  * This ScoreBoard calls gettimeofday() twice for each operation, so it does
36  * add a small amount of overhead.  If you have extremely high performance
37  * requirements, you could use QpsScoreBoard to track just the QPS rate and
38  * eliminate the gettimeofday() calls.
39  */
40 class LatencyScoreBoard : public ScoreBoard {
41  public:
42   class OpData {
43    public:
44     OpData();
45 
46     void addDataPoint(uint64_t latencyUsecs);
47 
48     void zero();
49     void accumulate(const OpData* other);
50 
51     uint64_t getCount() const;
52     uint64_t getCountSince(const OpData* other) const;
53     double getLatencyAvg() const;
54     double getLatencyAvgSince(const OpData* other) const;
55     double getLatencyPct(double pct) const;
56     double getLatencyPctSince(double pct, const OpData* other) const;
57     double getLatencyStdDev() const;
58     double getLatencyStdDevSince(const OpData* other) const;
59 
60     uint64_t count_;
61     uint64_t usecSum_;
62     uint64_t sumOfSquares_;
63 
64     // latency distribution histogram
65     folly::Histogram<uint64_t> latDistHist_;
66   };
67 
LatencyScoreBoard(uint32_t numOpsHint)68   explicit LatencyScoreBoard(uint32_t numOpsHint)
69       : startTime_(), opData_(numOpsHint) {}
70 
71   void opStarted(uint32_t opType) override;
72   void opSucceeded(uint32_t opType) override;
73   void opFailed(uint32_t opType) override;
74 
75   /**
76    * Get the OpData for a particular operation type
77    */
78   const OpData* getOpData(uint32_t opType);
79 
80   /**
81    * Compute an OpData object with aggregate information over all operation
82    * types.
83    *
84    * @param result A pointer to the OpData object to fill in with aggregate
85    *               information.
86    */
87   void computeOpAggregate(OpData* result) const;
88 
89   /**
90    * Zero out the statistics.
91    */
92   void zero();
93 
94   /**
95    * Add the counters from another scoreboard to this one.
96    */
97   void accumulate(const LatencyScoreBoard* other);
98 
99  private:
100   std::chrono::steady_clock::time_point startTime_;
101   ScoreBoardOpVector<OpData> opData_;
102 };
103 
104 } // namespace loadgen
105 } // namespace thrift
106 } // namespace apache
107 
108 #endif // THRIFT_TEST_LOADGEN_LATENCYSCOREBOARD_H_
109