• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "performance_analysis.h"
16 
17 #include <climits>
18 
19 #include "db_errno.h"
20 #include "macro_utils.h"
21 #include "time_helper.h"
22 #include "log_print.h"
23 #include "platform_specific.h"
24 
25 namespace DistributedDB {
26 const std::string PerformanceAnalysis::STATISTICAL_DATA_FILE_NAME_HEADER = "/data/log/statistic";
27 const std::string PerformanceAnalysis::CSV_FILE_EXTENSION = ".csv";
28 const std::string PerformanceAnalysis::DEFAULT_FILE_NAME = "default00";
29 
GetInstance(int stepNum)30 PerformanceAnalysis *PerformanceAnalysis::GetInstance(int stepNum)
31 {
32     static PerformanceAnalysis inst(stepNum);
33     return &inst;
34 }
35 
PerformanceAnalysis(uint32_t inStepNum)36 PerformanceAnalysis::PerformanceAnalysis(uint32_t inStepNum)
37     : isOpen_(false)
38 {
39     if (inStepNum == 0) {
40         stepNum_ = 0;
41     }
42     stepNum_ = inStepNum;
43     counts_.resize(stepNum_);
44     timeRecordData_.timeInfo.resize(stepNum_);
45     stepTimeRecordInfo_.resize(stepNum_);
46     for (auto &stepIter : stepTimeRecordInfo_) {
47         stepIter.max = 0;
48         stepIter.min = ULLONG_MAX;
49         stepIter.average = 0;
50     }
51     for (std::vector<uint64_t>::iterator iter = counts_.begin(); iter != counts_.end(); ++iter) {
52         *iter = 0;
53     }
54     fileNumber_ = 0;
55     fileID_ = std::string(DEFAULT_FILE_NAME) + std::to_string(fileNumber_);
56 }
57 
~PerformanceAnalysis()58 PerformanceAnalysis::~PerformanceAnalysis() {};
59 
IsStepValid(uint32_t step) const60 bool PerformanceAnalysis::IsStepValid(uint32_t step) const
61 {
62     if (stepNum_ >= MAX_TIMERECORD_STEP_NUM) {
63         return false;
64     }
65 
66     if (step < stepNum_) {
67         return true;
68     }
69     return false;
70 }
71 
IsOpen() const72 bool PerformanceAnalysis::IsOpen() const
73 {
74     return isOpen_;
75 }
76 
OpenPerformanceAnalysis()77 void PerformanceAnalysis::OpenPerformanceAnalysis()
78 {
79     isOpen_ = true;
80 }
81 
ClosePerformanceAnalysis()82 void PerformanceAnalysis::ClosePerformanceAnalysis()
83 {
84     isOpen_ = false;
85 }
86 
InsertTimeRecord(const TimePair & timePair,uint32_t step)87 bool PerformanceAnalysis::InsertTimeRecord(const TimePair &timePair, uint32_t step)
88 {
89     if (!IsStepValid(step)) {
90         return false;
91     }
92     timeRecordData_.timeInfo[step] = timePair;
93     return true;
94 }
95 
GetTimeRecord(uint32_t step,TimePair & timePair) const96 bool PerformanceAnalysis::GetTimeRecord(uint32_t step, TimePair &timePair) const
97 {
98     if (!IsStepValid(step)) {
99         return false;
100     }
101     timePair = timeRecordData_.timeInfo[step];
102     return true;
103 }
104 
TimeRecordStart()105 void PerformanceAnalysis::TimeRecordStart()
106 {
107     if (!IsOpen()) {
108         return;
109     }
110     StepTimeRecordStart(0);
111 }
112 
TimeRecordEnd()113 void PerformanceAnalysis::TimeRecordEnd()
114 {
115     if (!IsOpen()) {
116         return;
117     }
118     StepTimeRecordEnd(0);
119 }
120 
StepTimeRecordStart(uint32_t step)121 void PerformanceAnalysis::StepTimeRecordStart(uint32_t step)
122 {
123     if (!IsOpen()) {
124         return;
125     }
126     if (!IsStepValid(step)) {
127         return;
128     }
129     TimePair timePair = {0, 0};
130     uint64_t curTime = 0;
131     int errCode = OS::GetCurrentSysTimeInMicrosecond(curTime);
132     if (errCode != E_OK) {
133         LOGE("[performance_analysis] GetCurrentSysTimeInMicrosecond fail");
134     } else {
135         timePair.startTime = curTime;
136         LOGD("[performance_analysis] StepTimeRecordStart step:%d, curTime:%lu", step, curTime);
137         (void)InsertTimeRecord(timePair, step);
138     }
139 }
140 
StepTimeRecordEnd(uint32_t step)141 void PerformanceAnalysis::StepTimeRecordEnd(uint32_t step)
142 {
143     if (!IsOpen()) {
144         return;
145     }
146     if (!IsStepValid(step)) {
147         return;
148     }
149     TimePair timePair = {0, 0};
150     bool errCode = GetTimeRecord(step, timePair);
151     if (!errCode) {
152         return;
153     }
154     (void)InsertTimeRecord({0, 0}, step);
155 
156     uint64_t curTime = 0;
157     (void)OS::GetCurrentSysTimeInMicrosecond(curTime);
158     timePair.endTime = curTime;
159     LOGD("[performance_analysis] StepTimeRecordEnd step:%d, curTime:%lu", step, curTime);
160 
161     if ((timePair.endTime < timePair.startTime) || (timePair.startTime == 0) || (timePair.endTime == 0)) {
162         return;
163     }
164     TimeStamp offset = timePair.endTime - timePair.startTime;
165     if (stepTimeRecordInfo_[step].max < offset) {
166         stepTimeRecordInfo_[step].max = offset;
167     }
168     if (offset < stepTimeRecordInfo_[step].min) {
169         stepTimeRecordInfo_[step].min = offset;
170     }
171     counts_[step]++;
172     if (counts_[step] == 0) {
173         stepTimeRecordInfo_[step].average = 0;
174         return;
175     }
176     stepTimeRecordInfo_[step].average += (static_cast<float>(offset) -
177         stepTimeRecordInfo_[step].average) / counts_[step];
178 }
179 
GetStatistics()180 std::string PerformanceAnalysis::GetStatistics()
181 {
182     std::string result;
183     for (size_t i = 0; i < stepTimeRecordInfo_.size(); i++) {
184         if (stepTimeRecordInfo_[i].max != 0) {
185             result += "\nstep : " + std::to_string(i) + "\n";
186             result += "max:                 " + std::to_string(stepTimeRecordInfo_[i].max) + "\n";
187             result += "min:                 " + std::to_string(stepTimeRecordInfo_[i].min) + "\n";
188             result += "average:             " +
189                 std::to_string(static_cast<uint64_t>(stepTimeRecordInfo_[i].average)) + "\n";
190             result += "count:               " + std::to_string(counts_[i]) + "\n";
191         }
192     }
193     OutStatistics();
194     Clear();
195     return result;
196 }
197 
OutStatistics()198 void PerformanceAnalysis::OutStatistics()
199 {
200     std::string addrStatistics = STATISTICAL_DATA_FILE_NAME_HEADER + fileID_ + CSV_FILE_EXTENSION;
201     outFile.open(addrStatistics, std::ios_base::app);
202     // This part filters the zeros data
203     outFile << "stepNum" << "," << "maxTime(us)" << "," << "minTime(us)" << "," << "averageTime(us)"
204         << "," << "count" << "," << "\n";
205     for (size_t i = 0; i < stepTimeRecordInfo_.size(); i++) { // output to performance file
206         if (stepTimeRecordInfo_[i].max != 0) {
207             outFile << i << "," << stepTimeRecordInfo_[i].max<< "," << stepTimeRecordInfo_[i].min
208                 << "," << stepTimeRecordInfo_[i].average << "," << counts_[i] << "," << "\n";
209         }
210     }
211     LOGD("outFile success and exit!");
212     outFile.close();
213 }
214 
Clear()215 void PerformanceAnalysis::Clear()
216 {
217     counts_.clear();
218     timeRecordData_.timeInfo.clear();
219     stepTimeRecordInfo_.clear();
220     counts_.resize(stepNum_);
221     timeRecordData_.timeInfo.resize(stepNum_);
222     stepTimeRecordInfo_.resize(stepNum_);
223     for (auto &iter : stepTimeRecordInfo_) {
224         iter.max = 0;
225         iter.min = ULLONG_MAX;
226         iter.average = 0;
227     }
228     fileID_ = std::string(DEFAULT_FILE_NAME) + std::to_string(fileNumber_);
229 }
230 
SetFileNumber(const std::string & FileID)231 void PerformanceAnalysis::SetFileNumber(const std::string &FileID)
232 {
233     fileID_ = FileID;
234 }
235 }  // namespace DistributedDB
236