1 /*
2 * Copyright (c) 2022 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 "app_event_db_cleaner.h"
16
17 #include "app_event_cache.h"
18 #include "file_util.h"
19 #include "hilog/log.h"
20
21 namespace OHOS {
22 namespace HiviewDFX {
23 namespace {
24 const HiLogLabel LABEL = { LOG_CORE, 0xD002D07, "HiAppEvent_DbCleaner" };
25 const std::string DATABASE_DIR = "databases/";
26 }
GetFilesSize()27 uint64_t AppEventDbCleaner::GetFilesSize()
28 {
29 return FileUtil::GetDirSize(path_ + DATABASE_DIR);
30 }
31
ClearSpace(uint64_t curSize,uint64_t maxSize)32 uint64_t AppEventDbCleaner::ClearSpace(uint64_t curSize, uint64_t maxSize)
33 {
34 HiLog::Info(LABEL, "start to clear the space occupied by database files");
35 if (curSize <= maxSize) {
36 return curSize;
37 }
38 std::map<std::string, std::pair<int, int64_t>> blocksStat;
39 int result = AppEventCache::GetInstance()->GetBlocksStat(blocksStat);
40 if (result != 0 || blocksStat.empty()) {
41 return curSize;
42 }
43
44 uint64_t nowSize = curSize;
45 uint64_t otherSize = curSize - GetFilesSize();
46 const int TIMES = 10; // remove 1/10 records each time
47 for (int i = 0; i < TIMES; ++i) {
48 for (auto it = blocksStat.begin(); it != blocksStat.end();) {
49 std::pair<int, int64_t>& statPair = it->second;
50 if (statPair.first == 0) {
51 it = blocksStat.erase(it);
52 continue;
53 }
54 int delNum = statPair.first / TIMES;
55 if (delNum == 0) {
56 // data in table less than 10 records will remove at one time
57 delNum = statPair.first;
58 // mark as 0, will remove from map at next loop
59 statPair.first = 0;
60 }
61
62 // delete the records in the block
63 auto block = AppEventCache::GetInstance()->GetBlock(it->first);
64 if (block->Remove(delNum) != 0) {
65 ++it;
66 HiLog::Error(LABEL, "failed to delete record in block=%{public}s", it->first.c_str());
67 continue;
68 }
69
70 // update the now size of db file
71 nowSize = otherSize + GetFilesSize();
72 if (nowSize <= maxSize) {
73 return nowSize;
74 }
75 ++it;
76 }
77 }
78 return nowSize;
79 }
80
ClearData()81 void AppEventDbCleaner::ClearData()
82 {
83 HiLog::Info(LABEL, "start to clear the db data");
84 if (AppEventCache::GetInstance()->Close() != 0) {
85 HiLog::Error(LABEL, "failed to clear the db data");
86 }
87 }
88 } // namespace HiviewDFX
89 } // namespace OHOS
90