已开启
优化意图开机性能 #20320
linjunjie6创建于 8 天前
优化意图开机性能 #20320
已开启
共 7 个文件变更+69-151
| @@ -68,7 +68,6 @@ private: | |||
| 68 | int32_t userId_ = -1; | 68 | int32_t userId_ = -1; |
| 69 | bool cacheLoadFailed_ = false; | 69 | bool cacheLoadFailed_ = false; |
| 70 | mutable std::mutex genericInfosMutex_; | 70 | mutable std::mutex genericInfosMutex_; |
| 71 | - std::map<std::string, std::vector<ExtractInsightIntentGenericInfo>> intentGenericInfos_; | ||
| 72 | std::map<std::string, std::string> bundleVersionMap_; | 71 | std::map<std::string, std::string> bundleVersionMap_; |
| 73 | }; | 72 | }; |
| 74 | } // namespace AbilityRuntime | 73 | } // namespace AbilityRuntime |
| @@ -28,6 +28,7 @@ namespace AbilityRuntime { | |||
| 28 | class InsightRdbStorageMgr : public std::enable_shared_from_this<InsightRdbStorageMgr> { | 28 | class InsightRdbStorageMgr : public std::enable_shared_from_this<InsightRdbStorageMgr> { |
| 29 | DECLARE_DELAYED_SINGLETON(InsightRdbStorageMgr) | 29 | DECLARE_DELAYED_SINGLETON(InsightRdbStorageMgr) |
| 30 | public: | 30 | public: |
| 31 | + int32_t LoadInsightIntentBundleInfos(const int32_t userId, std::map<std::string, std::string> &bundleVersionMap); | ||
| 31 | int32_t LoadInsightIntentInfos(const int32_t userId, std::map<std::string, std::string> &bundleVersionMap, | 32 | int32_t LoadInsightIntentInfos(const int32_t userId, std::map<std::string, std::string> &bundleVersionMap, |
| 32 | std::vector<ExtractInsightIntentInfo> &totalInfos, std::vector<InsightIntentInfo> &configInfos); | 33 | std::vector<ExtractInsightIntentInfo> &totalInfos, std::vector<InsightIntentInfo> &configInfos); |
| 33 | int32_t LoadConfigInsightIntentInfos( | 34 | int32_t LoadConfigInsightIntentInfos( |
| @@ -46,6 +46,28 @@ std::vector<std::string> SplitStringBySlash(const std::string& inputStr) | |||
| 46 | return result; | 46 | return result; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | +int32_t InsightRdbStorageMgr::LoadInsightIntentBundleInfos(const int32_t userId, | ||
| 50 | + std::map<std::string, std::string> &bundleVersionMap) | ||
| 51 | +{ | ||
| 52 | + TAG_LOGD(AAFwkTag::INTENT, "Load intent bundle infos for userId:%{public}d", userId); | ||
| 53 | + std::unordered_map<std::string, std::string> value; | ||
| 54 | + std::string key = std::to_string(userId).append("/"); | ||
| 55 | + bool result = DelayedSingleton<InsightIntentRdbDataMgr>::GetInstance()->QueryDataBeginWithKey(key, value); | ||
| 56 | + if (!result) { | ||
| 57 | + TAG_LOGE(AAFwkTag::INTENT, "get entries error"); | ||
| 58 | + return ERR_INVALID_VALUE; | ||
| 59 | + } | ||
| 60 | + for (const auto &item : value) { | ||
| 61 | + std::vector<std::string> res = SplitStringBySlash(item.first); | ||
| 62 | + if (res.size() < INTENT_KEY_LENGTH) { | ||
| 63 | + TAG_LOGW(AAFwkTag::INTENT, "invalid intent key"); | ||
| 64 | + continue; | ||
| 65 | + } | ||
| 66 | + bundleVersionMap[res[BUNDLE_NAME]] = res[VERSION]; | ||
| 67 | + } | ||
| 68 | + return ERR_OK; | ||
| 69 | +} | ||
| 70 | + | ||
| 49 | int32_t InsightRdbStorageMgr::LoadInsightIntentInfos(const int32_t userId, | 71 | int32_t InsightRdbStorageMgr::LoadInsightIntentInfos(const int32_t userId, |
| 50 | std::map<std::string, std::string> &bundleVersionMap, std::vector<ExtractInsightIntentInfo> &totalInfos, | 72 | std::map<std::string, std::string> &bundleVersionMap, std::vector<ExtractInsightIntentInfo> &totalInfos, |
| 51 | std::vector<InsightIntentInfo> &configInfos) | 73 | std::vector<InsightIntentInfo> &configInfos) |
Mtest/unittest/ability_manager_service_thirteenth_test/mock/include/mock_insight_intent_db_cache.h+0-1
| @@ -65,7 +65,6 @@ private: | |||
| 65 | int32_t userId_ = -1; | 65 | int32_t userId_ = -1; |
| 66 | bool cacheLoadFailed_ = false; | 66 | bool cacheLoadFailed_ = false; |
| 67 | mutable std::mutex genericInfosMutex_; | 67 | mutable std::mutex genericInfosMutex_; |
| 68 | - std::map<std::string, std::vector<ExtractInsightIntentGenericInfo>> intentGenericInfos_; | ||
| 69 | std::map<std::string, std::string> bundleVersionMap_; | 68 | std::map<std::string, std::string> bundleVersionMap_; |
| 70 | }; | 69 | }; |
| 71 | } // namespace AbilityRuntime | 70 | } // namespace AbilityRuntime |
Mtest/unittest/ability_manager_service_thirteenth_test/mock/src/mock_insight_intent_db_cache.cpp+12-62
| @@ -28,31 +28,15 @@ int32_t InsightIntentDbCache::InitInsightIntentCache(const int32_t userId) | |||
| 28 | TAG_LOGD(AAFwkTag::INTENT, "no need init, userId %{public}d.", userId_); | 28 | TAG_LOGD(AAFwkTag::INTENT, "no need init, userId %{public}d.", userId_); |
| 29 | return ERR_INVALID_VALUE; | 29 | return ERR_INVALID_VALUE; |
| 30 | } | 30 | } |
| 31 | - std::vector<ExtractInsightIntentInfo> totalInfos; | 31 | + bundleVersionMap_.clear(); |
| 32 | - std::vector<InsightIntentInfo> configInfos; | ||
| 33 | std::map<std::string, std::string> bundleVersionMap; | 32 | std::map<std::string, std::string> bundleVersionMap; |
| 34 | - totalInfos.clear(); | 33 | + if (DelayedSingleton<InsightRdbStorageMgr>::GetInstance()->LoadInsightIntentBundleInfos( |
| 35 | - configInfos.clear(); | 34 | + userId, bundleVersionMap) != ERR_OK) { |
| 36 | - intentGenericInfos_.clear(); | 35 | + TAG_LOGE(AAFwkTag::INTENT, "Load BundleVersionMap failed"); |
| 37 | - if (DelayedSingleton<InsightRdbStorageMgr>::GetInstance()->LoadInsightIntentInfos( | ||
| 38 | - userId, bundleVersionMap, totalInfos, configInfos) != ERR_OK) { | ||
| 39 | - TAG_LOGE(AAFwkTag::INTENT, "Load All IntentData failed"); | ||
| 40 | cacheLoadFailed_ = true; | 36 | cacheLoadFailed_ = true; |
| 41 | return ERR_INVALID_VALUE; | 37 | return ERR_INVALID_VALUE; |
| 42 | } | 38 | } |
| 43 | - if (totalInfos.size() == 0) { | 39 | + bundleVersionMap_ = bundleVersionMap; |
| 44 | - TAG_LOGW(AAFwkTag::INTENT, "empty intent"); | ||
| 45 | - return ERR_NULL_INTENT; | ||
| 46 | - } | ||
| 47 | - for (size_t i = 0; i < totalInfos.size(); i++) { | ||
| 48 | - ExtractInsightIntentInfo info = totalInfos.at(i); | ||
| 49 | - std::string bundleName = info.genericInfo.bundleName; | ||
| 50 | - intentGenericInfos_[bundleName].push_back(info.genericInfo); | ||
| 51 | - auto versionIt = bundleVersionMap.find(bundleName); | ||
| 52 | - if (versionIt != bundleVersionMap.end()) { | ||
| 53 | - bundleVersionMap_[bundleName] = versionIt->second; | ||
| 54 | - } | ||
| 55 | - } | ||
| 56 | userId_ = userId; | 40 | userId_ = userId; |
| 57 | cacheLoadFailed_ = false; | 41 | cacheLoadFailed_ = false; |
| 58 | return ERR_OK; | 42 | return ERR_OK; |
| @@ -70,27 +54,6 @@ int32_t InsightIntentDbCache::SaveInsightIntentTotalInfo(const std::string &bund | |||
| 70 | TAG_LOGE(AAFwkTag::INTENT, "The userId %{public}d. is not the cache userId %{public}d.", userId, userId_); | 54 | TAG_LOGE(AAFwkTag::INTENT, "The userId %{public}d. is not the cache userId %{public}d.", userId, userId_); |
| 71 | return ERR_INVALID_VALUE; | 55 | return ERR_INVALID_VALUE; |
| 72 | } | 56 | } |
| 73 | - std::vector<ExtractInsightIntentGenericInfo> genericInfos; | ||
| 74 | - for (auto profileInfo : profileInfos.insightIntents) { | ||
| 75 | - ExtractInsightIntentInfo info; | ||
| 76 | - ExtractInsightIntentProfile::ProfileInfoFormat(profileInfo, info); | ||
| 77 | - ExtractInsightIntentGenericInfo genericInfo = info.genericInfo; | ||
| 78 | - genericInfos.emplace_back(genericInfo); | ||
| 79 | - } | ||
| 80 | - auto it = intentGenericInfos_.find(bundleName); | ||
| 81 | - if (it != intentGenericInfos_.end()) { | ||
| 82 | - TAG_LOGW(AAFwkTag::INTENT, "need update, bundleName %{public}s", bundleName.c_str()); | ||
| 83 | - for (auto iter = intentGenericInfos_[bundleName].begin(); iter != intentGenericInfos_[bundleName].end();) { | ||
| 84 | - if (iter->moduleName == moduleName) { | ||
| 85 | - iter = intentGenericInfos_[bundleName].erase(iter); | ||
| 86 | - } else { | ||
| 87 | - iter++; | ||
| 88 | - } | ||
| 89 | - } | ||
| 90 | - it->second.insert(it->second.end(), genericInfos.begin(), genericInfos.end()); | ||
| 91 | - } else { | ||
| 92 | - intentGenericInfos_[bundleName] = genericInfos; | ||
| 93 | - } | ||
| 94 | bundleVersionMap_[bundleName] = std::to_string(versionCode); | 57 | bundleVersionMap_[bundleName] = std::to_string(versionCode); |
| 95 | int32_t res = DelayedSingleton<InsightRdbStorageMgr>::GetInstance()->DeleteStorageInsightIntentData(bundleName, | 58 | int32_t res = DelayedSingleton<InsightRdbStorageMgr>::GetInstance()->DeleteStorageInsightIntentData(bundleName, |
| 96 | moduleName, userId); | 59 | moduleName, userId); |
| @@ -109,8 +72,7 @@ bool InsightIntentDbCache::HasInsightIntentByName(uint32_t versionCode, | |||
| 109 | TAG_LOGW(AAFwkTag::INTENT, "error userId %{public}d.", userId_); | 72 | TAG_LOGW(AAFwkTag::INTENT, "error userId %{public}d.", userId_); |
| 110 | return false; | 73 | return false; |
| 111 | } | 74 | } |
| 112 | - if (intentGenericInfos_.find(bundleName) != intentGenericInfos_.end() && | 75 | + if (bundleVersionMap_.find(bundleName) != bundleVersionMap_.end() && |
| 113 | - bundleVersionMap_.find(bundleName) != bundleVersionMap_.end() && | ||
| 114 | bundleVersionMap_[bundleName].compare(std::to_string(versionCode)) == 0) { | 76 | bundleVersionMap_[bundleName].compare(std::to_string(versionCode)) == 0) { |
| 115 | return true; | 77 | return true; |
| 116 | } | 78 | } |
| @@ -144,20 +106,7 @@ bool InsightIntentDbCache::DeleteInsightIntentTotalInfo(const std::string &bundl | |||
| 144 | } | 106 | } |
| 145 | std::lock_guard<std::mutex> lock(genericInfosMutex_); | 107 | std::lock_guard<std::mutex> lock(genericInfosMutex_); |
| 146 | if (moduleName.empty()) { | 108 | if (moduleName.empty()) { |
| 147 | - intentGenericInfos_.erase(bundleName); | ||
| 148 | bundleVersionMap_.erase(bundleName); | 109 | bundleVersionMap_.erase(bundleName); |
| 149 | - } else { | ||
| 150 | - for (auto iter = intentGenericInfos_[bundleName].begin(); iter != intentGenericInfos_[bundleName].end();) { | ||
| 151 | - if (iter->moduleName == moduleName) { | ||
| 152 | - iter = intentGenericInfos_[bundleName].erase(iter); | ||
| 153 | - } else { | ||
| 154 | - iter++; | ||
| 155 | - } | ||
| 156 | - } | ||
| 157 | - if (intentGenericInfos_[bundleName].size() == 0) { | ||
| 158 | - intentGenericInfos_.erase(bundleName); | ||
| 159 | - bundleVersionMap_.erase(bundleName); | ||
| 160 | - } | ||
| 161 | } | 110 | } |
| 162 | return DelayedSingleton<InsightRdbStorageMgr>::GetInstance()->DeleteStorageInsightIntentData(bundleName, | 111 | return DelayedSingleton<InsightRdbStorageMgr>::GetInstance()->DeleteStorageInsightIntentData(bundleName, |
| 163 | moduleName, userId) == ERR_OK; | 112 | moduleName, userId) == ERR_OK; |
| @@ -192,12 +141,13 @@ void InsightIntentDbCache::GetInsightIntentGenericInfoByName(const std::string & | |||
| 192 | void InsightIntentDbCache::GetInsightIntentGenericInfo(const std::string &bundleName, const std::string &moduleName, | 141 | void InsightIntentDbCache::GetInsightIntentGenericInfo(const std::string &bundleName, const std::string &moduleName, |
| 193 | const std::string &intentName, const int32_t userId, ExtractInsightIntentGenericInfo &genericInfo) | 142 | const std::string &intentName, const int32_t userId, ExtractInsightIntentGenericInfo &genericInfo) |
| 194 | { | 143 | { |
| 195 | - std::lock_guard<std::mutex> lock(genericInfosMutex_); | 144 | + ExtractInsightIntentInfo info; |
| 196 | - for (auto info : intentGenericInfos_[bundleName]) { | 145 | + if (DelayedSingleton<InsightRdbStorageMgr>::GetInstance()-> |
| 197 | - if (info.moduleName == moduleName && info.intentName == intentName) { | 146 | + LoadInsightIntentInfo(bundleName, moduleName, intentName, userId, info) != ERR_OK) { |
| 198 | - genericInfo = info; | 147 | + TAG_LOGW(AAFwkTag::INTENT, "GetInsightIntentInfo failed"); |
| 199 | - } | 148 | + return; |
| 200 | } | 149 | } |
| 150 | + genericInfo = info.genericInfo; | ||
| 201 | } | 151 | } |
| 202 | 152 | ||
| 203 | void InsightIntentDbCache::GetAllInsightIntentInfo(const int32_t userId, std::vector<ExtractInsightIntentInfo> &infos, | 153 | void InsightIntentDbCache::GetAllInsightIntentInfo(const int32_t userId, std::vector<ExtractInsightIntentInfo> &infos, |
| @@ -87,14 +87,28 @@ InsightRdbStorageMgr::~InsightRdbStorageMgr() | |||
| 87 | { | 87 | { |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | +int32_t InsightRdbStorageMgr::LoadInsightIntentBundleInfos(const int32_t userId, | ||
| 91 | + std::map<std::string, std::string> &bundleVersionMap) | ||
| 92 | +{ | ||
| 93 | + bundleVersionMap["mock.bundle"] = "0"; | ||
| 94 | + if (g_mockLoadInsightIntentInfosRet) { | ||
| 95 | + return ERR_OK; | ||
| 96 | + } | ||
| 97 | + return ERR_INVALID_VALUE; | ||
| 98 | +} | ||
| 99 | + | ||
| 90 | int32_t InsightRdbStorageMgr::LoadInsightIntentInfos(const int32_t userId, | 100 | int32_t InsightRdbStorageMgr::LoadInsightIntentInfos(const int32_t userId, |
| 91 | std::map<std::string, std::string> &bundleVersionMap, | 101 | std::map<std::string, std::string> &bundleVersionMap, |
| 92 | std::vector<ExtractInsightIntentInfo> &totalInfos, std::vector<InsightIntentInfo> &configInfos) | 102 | std::vector<ExtractInsightIntentInfo> &totalInfos, std::vector<InsightIntentInfo> &configInfos) |
| 93 | { | 103 | { |
| 94 | ExtractInsightIntentInfo totalInfo; | 104 | ExtractInsightIntentInfo totalInfo; |
| 95 | InsightIntentInfo configInfo; | 105 | InsightIntentInfo configInfo; |
| 106 | + totalInfo.genericInfo.bundleName = "mock.bundle"; | ||
| 107 | + totalInfo.genericInfo.moduleName = "mockModule"; | ||
| 108 | + totalInfo.genericInfo.intentName = "mockIntent"; | ||
| 96 | totalInfos.push_back(totalInfo); | 109 | totalInfos.push_back(totalInfo); |
| 97 | configInfos.push_back(configInfo); | 110 | configInfos.push_back(configInfo); |
| 111 | + bundleVersionMap["mock.bundle"] = "0"; | ||
| 98 | if (g_mockLoadInsightIntentInfosRet) { | 112 | if (g_mockLoadInsightIntentInfosRet) { |
| 99 | return ERR_OK; | 113 | return ERR_OK; |
| 100 | } | 114 | } |
| @@ -122,6 +136,9 @@ int32_t InsightRdbStorageMgr::LoadInsightIntentInfoByName(const std::string &bu | |||
| 122 | std::vector<ExtractInsightIntentInfo> &totalInfos) | 136 | std::vector<ExtractInsightIntentInfo> &totalInfos) |
| 123 | { | 137 | { |
| 124 | ExtractInsightIntentInfo totalInfo; | 138 | ExtractInsightIntentInfo totalInfo; |
| 139 | + totalInfo.genericInfo.bundleName = bundleName; | ||
| 140 | + totalInfo.genericInfo.moduleName = "mockModule"; | ||
| 141 | + totalInfo.genericInfo.intentName = "mockIntent"; | ||
| 125 | totalInfos.push_back(totalInfo); | 142 | totalInfos.push_back(totalInfo); |
| 126 | if (g_mockLoadInsightIntentInfoByNameRet) { | 143 | if (g_mockLoadInsightIntentInfoByNameRet) { |
| 127 | return ERR_OK; | 144 | return ERR_OK; |


🤖 AI 代码检视意见(回复本评论可解决检视意见,点击被检视代码行左侧的小头像可收起检视意见)
🟡 InitInsightIntentCache对bundleVersionMap_的clear与load未加锁保护
位置:
L34-L47| 严重程度: Medium❓ 问题描述
InitInsightIntentCache中直接调用bundleVersionMap_.clear()及通过LoadInsightIntentBundleInfos填充bundleVersionMap_,期间未持有genericInfosMutex_。若该流程与其他修改bundleVersionMap_的接口(如SaveInsightIntentTotalInfo/DeleteInsightIntentTotalInfo)并发,将产生数据竞争与迭代器失效。虽然userId_检查可提供部分隐式同步,但属于隐性约定,不可靠。
💡 修复建议
修改建议:在InitInsightIntentCache修改bundleVersionMap_的整个临界区(clear + load)外层加锁,与其他读写bundleVersionMap_的接口使用同一把genericInfosMutex_串行化访问,避免数据竞争。
34: { 35: std::lock_guardstd::mutex lock(genericInfosMutex_); 36: bundleVersionMap_.clear(); 37: 38: if (DelayedSingleton::GetInstance()->LoadInsightIntentBundleInfos(
39: userId, bundleVersionMap_) != ERR_OK) {
40: TAG_LOGE(AAFwkTag::INTENT, "Load BundleVersionMap failed");
41: cacheLoadFailed_ = true;
42: return ERR_INVALID_VALUE;
43: }
44: userId_ = userId;
45: cacheLoadFailed_ = false;
46: }
47: TAG_LOGI(AAFwkTag::INTENT, "Init intent done, userId:%{public}d, bundleCount:%{public}zu",