• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "cloud_daemon_statistic.h"
17 
18 #include <fcntl.h>
19 #include <fstream>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 
23 #include "utils_log.h"
24 
25 namespace OHOS {
26 namespace FileManagement {
27 namespace CloudFile {
28 using namespace std;
29 
30 #define FILE_SIZE_BYTE_TO_KB 1024
31 #define FILE_SIZE_KB_TO_MB 1024
32 #define STAT_TIME_MS_TO_S 1000
33 #define CLOUD_FILE_DIR_MOD 0770
34 #define CLOUD_FILE_MOD 0660
35 
36 static const string STAT_DATA_DIR_NAME = "/data/service/el1/public/cloudfile/cloud_data_statistic";
37 static const string STAT_DATA_FILE_NAME = "cloud_sync_read_file_stat";
38 static const vector<uint64_t> OPEN_SIZE_RANGE_VECTOR = { 256, 512, 1 * FILE_SIZE_KB_TO_MB, 2 * FILE_SIZE_KB_TO_MB,
39     4 * FILE_SIZE_KB_TO_MB, 6 * FILE_SIZE_KB_TO_MB, 8 * FILE_SIZE_KB_TO_MB, 15 * FILE_SIZE_KB_TO_MB };
40 static const vector<uint64_t> OPEN_TIME_RANGE_VECTOR = { 250, 500, 1000, 1500, 2000, 5000 };
41 static const vector<uint64_t> READ_SIZE_RANGE_VECTOR = { 128, 256, 512, 1 * FILE_SIZE_KB_TO_MB, 2 * FILE_SIZE_KB_TO_MB,
42     4 * FILE_SIZE_KB_TO_MB };
43 static const vector<uint64_t> READ_TIME_RANGE_VECTOR = { 300, 600, 900, 1200, 1500, 2000, 3000, 5000, 8000 };
44 
GetRangeIndex(uint64_t value,const vector<uint64_t> rangeVector)45 static uint32_t GetRangeIndex(uint64_t value, const vector<uint64_t> rangeVector)
46 {
47     uint32_t index = 0;
48     for (; index < rangeVector.size(); index++) {
49         if (value <= rangeVector[index]) {
50             break;
51         }
52     }
53     return index;
54 }
55 
CheckOverflow(uint64_t & data,uint64_t addValue)56 static void CheckOverflow(uint64_t &data, uint64_t addValue)
57 {
58     if (data >= UINT64_MAX - addValue) {
59         LOGE("update fail, overflow, data = %{public}llu, addValue = %{public}llu",
60             static_cast<unsigned long long>(data),
61             static_cast<unsigned long long>(addValue));
62         data = 0;
63     } else {
64         data += addValue;
65     }
66 }
67 
UpdateOpenSizeStat(uint64_t size)68 void CloudDaemonStatistic::UpdateOpenSizeStat(uint64_t size)
69 {
70     uint32_t index = GetRangeIndex(size / FILE_SIZE_BYTE_TO_KB, OPEN_SIZE_RANGE_VECTOR);
71     if (index >= OPEN_SIZE_MAX) {
72         LOGE("update open size stat fail, index overflow, index = %{public}u.", index);
73         return;
74     }
75     CheckOverflow(openSizeStat_[index], 1);
76 }
77 
UpdateOpenTimeStat(uint32_t type,uint64_t time)78 void CloudDaemonStatistic::UpdateOpenTimeStat(uint32_t type, uint64_t time)
79 {
80     uint32_t index = GetRangeIndex(time, OPEN_TIME_RANGE_VECTOR);
81     if (index >= OPEN_TIME_MAX) {
82         LOGE("update open time stat fail, index overflow, index = %{public}u.", index);
83         return;
84     }
85     CheckOverflow(openTimeStat_[type][index], 1);
86 }
87 
UpdateReadSizeStat(uint64_t size)88 void CloudDaemonStatistic::UpdateReadSizeStat(uint64_t size)
89 {
90     uint32_t index = GetRangeIndex(size / FILE_SIZE_BYTE_TO_KB, READ_SIZE_RANGE_VECTOR);
91     if (index >= READ_SIZE_MAX) {
92         LOGE("update read size stat fail, index overflow, index = %{public}u.", index);
93         return;
94     }
95     CheckOverflow(readSizeStat_[index], 1);
96 }
97 
UpdateReadTimeStat(uint64_t size,uint64_t time)98 void CloudDaemonStatistic::UpdateReadTimeStat(uint64_t size, uint64_t time)
99 {
100     uint32_t indexSize = GetRangeIndex(size / FILE_SIZE_BYTE_TO_KB, READ_SIZE_RANGE_VECTOR);
101     uint32_t indexTime = GetRangeIndex(time, READ_TIME_RANGE_VECTOR);
102     if (indexSize >= READ_SIZE_MAX || indexTime >= READ_TIME_MAX) {
103         LOGE("update read time stat fail, index overflow, indexSize = %{public}u, indexTime = %{public}u.",
104             indexSize, indexTime);
105         return;
106     }
107     CheckOverflow(readTimeStat_[indexSize][indexTime], 1);
108 }
109 
AddFileData()110 void CloudDaemonStatistic::AddFileData()
111 {
112     /* file not exist means first time, no former data, normal case */
113     auto ret = access(STAT_DATA_DIR_NAME.c_str(), F_OK);
114     if (ret != 0) {
115         LOGI("dir cloud_data_statistic not exist, ret = %{public}d.", ret);
116         return;
117     }
118     std::ifstream statDataFile(STAT_DATA_DIR_NAME + "/" + STAT_DATA_FILE_NAME);
119     if (!statDataFile) {
120         LOGI("file cloud_sync_read_file_stat not exist.");
121         return;
122     }
123 
124     uint64_t tmpData;
125     for (uint32_t i = 0; i < OPEN_SIZE_MAX; i++) {
126         statDataFile >> tmpData;
127         CheckOverflow(openSizeStat_[i], tmpData);
128     }
129     for (uint32_t i = 0; i < FILE_TYPE_MAX; i++) {
130         for (uint32_t j = 0; j < OPEN_TIME_MAX; j++) {
131             statDataFile >> tmpData;
132             CheckOverflow(openTimeStat_[i][j], tmpData);
133         }
134     }
135     for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
136         statDataFile >> tmpData;
137         CheckOverflow(readSizeStat_[i], tmpData);
138     }
139     for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
140         for (uint32_t j = 0; j < READ_TIME_MAX; j++) {
141             statDataFile >> tmpData;
142             CheckOverflow(readTimeStat_[i][j], tmpData);
143         }
144     }
145     statDataFile.close();
146 }
147 
OutputToFile()148 void CloudDaemonStatistic::OutputToFile()
149 {
150     string tmpStr = "";
151 
152     if (access(STAT_DATA_DIR_NAME.c_str(), F_OK) != 0) {
153         auto ret = mkdir(STAT_DATA_DIR_NAME.c_str(), CLOUD_FILE_DIR_MOD);
154         if (ret != 0) {
155             LOGE("mkdir cloud_data_statistic fail, ret = %{public}d.", ret);
156             return;
157         }
158     }
159     string statFilePath = STAT_DATA_DIR_NAME + "/" + STAT_DATA_FILE_NAME;
160     if (access(statFilePath.c_str(), F_OK) != 0) {
161         auto fd = creat(statFilePath.c_str(), CLOUD_FILE_MOD);
162         if (fd < 0) {
163             LOGE("create file cloud_sync_read_file_stat fail.");
164             return;
165         }
166         close(fd);
167     }
168 
169     std::ofstream statDataFile(statFilePath);
170     if (!statDataFile) {
171         LOGE("open out stream file cloud_sync_read_file_stat fail.");
172         return;
173     }
174 
175     for (uint32_t i = 0; i < OPEN_SIZE_MAX; i++) {
176         tmpStr += (to_string(openSizeStat_[i]) + " ");
177     }
178     statDataFile << tmpStr << endl << endl;
179     tmpStr = "";
180 
181     for (uint32_t i = 0; i < FILE_TYPE_MAX; i++) {
182         for (uint32_t j = 0; j < OPEN_TIME_MAX; j++) {
183             tmpStr += (to_string(openTimeStat_[i][j]) + " ");
184         }
185         tmpStr += "\n";
186     }
187     statDataFile << tmpStr << endl;
188     tmpStr = "";
189 
190     for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
191         tmpStr += (to_string(readSizeStat_[i]) + " ");
192     }
193     statDataFile << tmpStr << endl << endl;
194     tmpStr = "";
195 
196     for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
197         for (uint32_t j = 0; j < READ_TIME_MAX; j++) {
198             tmpStr += (to_string(readTimeStat_[i][j]) + " ");
199         }
200         tmpStr += "\n";
201     }
202     statDataFile << tmpStr << endl;
203     statDataFile.close();
204 }
205 
ClearStat()206 void CloudDaemonStatistic::ClearStat()
207 {
208     for (uint32_t i = 0; i < OPEN_SIZE_MAX; i++) {
209         openSizeStat_[i] = 0;
210     }
211     for (uint32_t i = 0; i < FILE_TYPE_MAX; i++) {
212         for (uint32_t j = 0; j < OPEN_TIME_MAX; j++) {
213             openTimeStat_[i][j] = 0;
214         }
215     }
216     for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
217         readSizeStat_[i] = 0;
218     }
219     for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
220         for (uint32_t j = 0; j < READ_TIME_MAX; j++) {
221             readTimeStat_[i][j] = 0;
222         }
223     }
224 }
225 
UpdateStatData()226 void CloudDaemonStatistic::UpdateStatData()
227 {
228     lock_guard<mutex> lock(mutex_);
229     AddFileData();
230     OutputToFile();
231     ClearStat();
232 }
233 
GetInstance()234 CloudDaemonStatistic &CloudDaemonStatistic::GetInstance()
235 {
236     static CloudDaemonStatistic instance_;
237     return instance_;
238 }
239 
240 } // namespace CloudFile
241 } // namespace FileManagement
242 } // namespace OHOS