1 /*
2 * Copyright (c) 2025 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 #define MLOG_TAG "AccurateRefresh::MutiThreadAssetMgr"
17 #include "multi_thread_asset_change_info_mgr.h"
18 #include "accurate_debug_log.h"
19
20 using namespace std;
21
22 namespace OHOS {
23 namespace Media::AccurateRefresh {
24
25 std::mutex MultiThreadAssetChangeInfoMgr::changeDataMutex_;
26
CheckInsertBeforeInfo(PhotoAssetChangeInfo & info)27 bool MultiThreadAssetChangeInfoMgr::CheckInsertBeforeInfo(PhotoAssetChangeInfo& info)
28 {
29 std::lock_guard<std::mutex> lock(changeDataMutex_);
30 auto iter = assetChangeDataMap_.find(info.fileId_);
31 // 第一次插入fileId
32 if (iter == assetChangeDataMap_.end()) {
33 MultiThreadAssetChangeData multiThreadChangeData;
34 multiThreadChangeData.count_ = 1;
35 multiThreadChangeData.infoBefore_ = info;
36 assetChangeDataMap_.emplace(info.fileId_, multiThreadChangeData);
37 ACCURATE_DEBUG("first insert fieldId[%{public}d]", info.fileId_);
38 return false;
39 }
40
41 // 非第一次插入,不修改infoBefore_
42 auto &multiThreadChangeData = iter->second;
43 multiThreadChangeData.count_++;
44 multiThreadChangeData.isMultiOperation_ = true;
45 ACCURATE_INFO("multi insert, fileId[%{public}d] count[%{public}d]", info.fileId_, multiThreadChangeData.count_);
46 return true;
47 }
48
CheckInsertAfterInfo(PhotoAssetChangeInfo & info,bool isAdd)49 bool MultiThreadAssetChangeInfoMgr::CheckInsertAfterInfo(PhotoAssetChangeInfo& info, bool isAdd)
50 {
51 std::lock_guard<std::mutex> lock(changeDataMutex_);
52 auto iter = assetChangeDataMap_.find(info.fileId_);
53 if (iter == assetChangeDataMap_.end()) {
54 // isAdd场景下找不到为正常逻辑,不需要打印
55 if (!isAdd) {
56 MEDIA_ERR_LOG("no fileId[%{public}d]", info.fileId_);
57 }
58 return false;
59 }
60
61 // 更新infoAfter_信息
62 auto &multiThreadChangeData = iter->second;
63 // isAdd走到这个流程,说明Insert到Query之间执行了Update处理,需要修正count和before信息
64 if (isAdd) {
65 multiThreadChangeData.count_++;
66 multiThreadChangeData.isMultiOperation_ = true;
67 multiThreadChangeData.infoBefore_ = PhotoAssetChangeInfo();
68 }
69 if (!multiThreadChangeData.isMultiOperation_) {
70 assetChangeDataMap_.erase(iter);
71 ACCURATE_DEBUG("no multi thread, remove fieldId[%{public}d]", info.fileId_);
72 return false;
73 }
74 multiThreadChangeData.infoAfter_ = info;
75 return multiThreadChangeData.isMultiOperation_;
76 }
77
GetAssetChangeData(int32_t fileId)78 pair<PhotoAssetChangeInfo, PhotoAssetChangeInfo> MultiThreadAssetChangeInfoMgr::GetAssetChangeData(int32_t fileId)
79 {
80 std::lock_guard<std::mutex> lock(changeDataMutex_);
81 auto iter = assetChangeDataMap_.find(fileId);
82 if (iter == assetChangeDataMap_.end()) {
83 MEDIA_ERR_LOG("no fileId[%{public}d]", fileId);
84 return pair<PhotoAssetChangeInfo, PhotoAssetChangeInfo>(PhotoAssetChangeInfo(), PhotoAssetChangeInfo());
85 }
86 auto &multiThreadChangeData = iter->second;
87 return pair<PhotoAssetChangeInfo, PhotoAssetChangeInfo>(multiThreadChangeData.infoBefore_,
88 multiThreadChangeData.infoAfter_);
89 }
90
GetAndUpdateAssetChangeData(int32_t fileId)91 pair<PhotoAssetChangeInfo, PhotoAssetChangeInfo> MultiThreadAssetChangeInfoMgr::GetAndUpdateAssetChangeData(
92 int32_t fileId)
93 {
94 std::lock_guard<std::mutex> lock(changeDataMutex_);
95 auto iter = assetChangeDataMap_.find(fileId);
96 if (iter == assetChangeDataMap_.end()) {
97 MEDIA_ERR_LOG("no fileId[%{public}d]", fileId);
98 return pair<PhotoAssetChangeInfo, PhotoAssetChangeInfo>(PhotoAssetChangeInfo(), PhotoAssetChangeInfo());
99 }
100 auto &multiThreadChangeData = iter->second;
101 auto before = multiThreadChangeData.infoBefore_;
102 multiThreadChangeData.infoBefore_ = multiThreadChangeData.infoAfter_;
103 ACCURATE_DEBUG("update before: %{public}s, after: %{public}s", before.ToString(true).c_str(),
104 multiThreadChangeData.infoAfter_.ToString(true).c_str());
105 return pair<PhotoAssetChangeInfo, PhotoAssetChangeInfo>(before, multiThreadChangeData.infoAfter_);
106 }
107
ClearMultiThreadChangeData(int32_t fileId)108 void MultiThreadAssetChangeInfoMgr::ClearMultiThreadChangeData(int32_t fileId)
109 {
110 std::lock_guard<std::mutex> lock(changeDataMutex_);
111 auto iter = assetChangeDataMap_.find(fileId);
112 if (iter == assetChangeDataMap_.end()) {
113 MEDIA_ERR_LOG("no fileId[%{public}d]", fileId);
114 return;
115 }
116 auto &multiThreadChangeData = iter->second;
117 multiThreadChangeData.count_--;
118 if (multiThreadChangeData.count_ == 0) {
119 assetChangeDataMap_.erase(iter);
120 }
121 ACCURATE_DEBUG("multi erase, fileId[%{public}d] count[%{public}d]", fileId, multiThreadChangeData.count_);
122 }
123
124 } // namespace Media::AccurateRefresh
125 } // namespace OHOS