1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PERFORMANCE_ANALYSIS_H
17 #define PERFORMANCE_ANALYSIS_H
18 
19 #include <fstream>
20 #include <mutex>
21 #include <vector>
22 
23 #include "db_types.h"
24 
25 namespace DistributedDB {
26 enum PT_TEST_RECORDS : uint32_t {
27     RECORD_PUT_DATA = 1,
28     RECORD_SYNC_TOTAL,
29     RECORD_WATERMARK_SYNC,
30     RECORD_READ_DATA,
31     RECORD_SAVE_DATA,
32     RECORD_SAVE_LOCAL_WATERMARK,
33     RECORD_SAVE_PEER_WATERMARK,
34     RECORD_DATA_SEND_REQUEST_TO_ACK_RECV,
35     RECORD_DATA_REQUEST_RECV_TO_SEND_ACK,
36     RECORD_MACHINE_START_TO_PUSH_SEND,
37     RECORD_ACK_RECV_TO_USER_CALL_BACK,
38 };
39 
40 enum MV_TEST_RECORDS : uint32_t {
41     RECORD_SEND_LOCAL_DATA_CHANGED_TO_COMMIT_REQUEST_RECV = 3,
42     RECORD_GET_DEVICE_LATEST_COMMIT,
43     RECORD_COMMIT_SEND_REQUEST_TO_ACK_RECV,
44     RECORD_GET_COMMIT_TREE,
45     RECORD_DATA_GET_VALID_COMMIT,
46     RECORD_DATA_ENTRY_SEND_REQUEST_TO_ACK_RECV,
47     RECORD_GET_COMMIT_DATA,
48     RECORD_GET_VALUE_SLICE_NODE,
49     RECORD_VALUE_SLICE_SEND_REQUEST_TO_ACK_RECV,
50     RECORD_READ_VALUE_SLICE,
51     RECORD_SAVE_VALUE_SLICE,
52     RECORD_PUT_COMMIT_DATA,
53     RECORD_MERGE,
54 };
55 
56 struct TimePair {
57     Timestamp startTime = 0;
58     Timestamp endTime = 0;
59 };
60 
61 struct StatisticsInfo {
62     Timestamp max = 0;
63     Timestamp min = 0;
64     float average = 0.0;
65 };
66 
67 struct SingleStatistics {
68     std::vector<TimePair> timeInfo;
69 };
70 
71 class PerformanceAnalysis {
72 public:
73     static PerformanceAnalysis *GetInstance(int stepNum = 20);
74 
75     void Initialization();
76 
77     void TimeRecordStart();
78 
79     void TimeRecordEnd();
80 
81     void StepTimeRecordStart(uint32_t step);
82 
83     void StepTimeRecordEnd(uint32_t step);
84 
85     std::string GetStatistics();
86 
87     void OpenPerformanceAnalysis();
88 
89     void ClosePerformanceAnalysis();
90 
91     void SetFileName(const std::string &fileName);
92 
93 private:
94     explicit PerformanceAnalysis(uint32_t step);
95 
96     ~PerformanceAnalysis();
97 
98     bool IsStepValid(uint32_t step) const;
99 
100     bool IsOpen() const;
101 
102     bool InsertTimeRecord(const TimePair &timePair, uint32_t step);
103 
104     bool GetTimeRecord(uint32_t step, TimePair &timePair) const;
105 
106     void OutStatistics();
107 
108     void Clear();
109 
110     void Close();
111 
112     const static int MAX_TIMERECORD_STEP_NUM = 200;
113     const static std::string STATISTICAL_DATA_FILE_NAME_HEADER;
114     const static std::string CSV_FILE_EXTENSION;
115     const static std::string DEFAULT_FILE_NAME;
116     SingleStatistics timeRecordData_;
117     std::vector<StatisticsInfo> stepTimeRecordInfo_;
118     std::vector<uint64_t> counts_;
119     uint32_t stepNum_;
120     bool isOpen_;
121     std::ofstream outFile;
122     int fileNumber_;
123     std::string fileName_;
124     static std::once_flag initFlag_;
125 };
126 }  // namespace DistributedDB
127 #endif
128