diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index 9d7ab287b50aa7165e13750bb09d0f615b673912..373499fd1debacff3d29de23207f68197075cfd6 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -99,11 +99,21 @@ private: * @brief backup * * @param bigFileInfo bigfiles to be backup + * @param bigFileInfoBackuped bigfiles have been backuped * @param smallFiles smallfiles to be backup * @param includesNum sizeof includes * @param excludesNum sizeof excludes */ - int DoBackup(TarMap &bigFileInfo, map &smallFiles, uint32_t includesNum, uint32_t excludesNum); + int DoBackup(TarMap &bigFileInfo, TarMap &bigFileInfoBackuped, map &smallFiles, + uint32_t includesNum, uint32_t excludesNum); + + /** + * @brief backup + * + * @param bigFileInfo bigfiles to be backup + * @param backupedFileSize backuped file size + */ + int DoBackupBigFiles(TarMap &bigFileInfo, uint32_t backupedFileSize); /** * @brief restore @@ -113,6 +123,8 @@ private: int DoRestore(const string &fileName, const off_t fileSize); /** + * + + * * @brief incremental restore * */ @@ -210,7 +222,7 @@ private: int DoIncrementalBackupTask(UniqueFd incrementalFd, UniqueFd manifestFd); ErrCode IncrementalBigFileReady(TarMap &pkgInfo, const vector &bigInfos, sptr proxy); - ErrCode BigFileReady(TarMap &bigFileInfo, sptr proxy); + ErrCode BigFileReady(TarMap &bigFileInfo, sptr proxy, uint32_t BackupedFileSize); void WaitToSendFd(std::chrono::system_clock::time_point &startTime, int &fdSendNum); void RefreshTimeInfo(std::chrono::system_clock::time_point &startTime, int &fdSendNum); void IncrementalPacket(const vector &infos, TarMap &tar, sptr proxy); @@ -362,6 +374,12 @@ private: void OnRestoreExFinish(); void DoBackupStart(); void DoBackupEnd(); + void CalculateDataSizeTask(const string &config); + void DoBackUpTask(const string &config); + TarMap Transfer2Bigfiles(std::map files); + void PreDealExcludes(std::vector &excludes); + template + map MatchFiles(map files, vector endExcludes); private: pair> GetFileInfos(const vector &includes, const vector &excludes); void ReportAppStatistic(ErrCode errCode); diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index 849fb2b594aeabc3650b6092685d86d965259fd8..76dfa82fbcb1196e7f4decca990b7ea5ebaf807f 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -59,6 +59,7 @@ #include "sandbox_helper.h" #include "service_client.h" #include "tar_file.h" +#include "b_utils/scan_file_singleton.h" namespace OHOS::FileManagement::Backup { const string INDEX_FILE_BACKUP = string(BConstants::PATH_BUNDLE_BACKUP_HOME). @@ -498,13 +499,14 @@ void BackupExtExtension::ClearNoPermissionFiles(TarMap &pkgInfo, vector proxy) +ErrCode BackupExtExtension::BigFileReady(TarMap &bigFileInfo, sptr proxy, uint32_t BackupedFileSize) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - HILOGI("BigFileReady Begin: bigFileInfo file size is: %{public}zu", bigFileInfo.size()); + HILOGI("BigFileReady Begin: bigFileInfo file size is: %{public}zu, BackupedFileSize is %{public}d", + bigFileInfo.size(), BackupedFileSize); ErrCode ret {ERR_OK}; auto startTime = std::chrono::system_clock::now(); - int fdNum = 0; + int fdNum = BackupedFileSize; vector noPermissionFiles; for (auto &item : bigFileInfo) { WaitToSendFd(startTime, fdNum); @@ -530,7 +532,7 @@ ErrCode BackupExtExtension::BigFileReady(TarMap &bigFileInfo, sptr pro RefreshTimeInfo(startTime, fdNum); } ClearNoPermissionFiles(bigFileInfo, noPermissionFiles); - HILOGI("BigFileReady End"); + HILOGI("BigFileReady End, fdNum is %{public}d", fdNum); return ret; } @@ -777,11 +779,12 @@ void BackupExtExtension::DoPacket(const map &srcFiles, TarMap &t appStatistic_->tarSpend_ = totalTarUs / MS_TO_US; } -int BackupExtExtension::DoBackup(TarMap &bigFileInfo, map &smallFiles, +int BackupExtExtension::DoBackup(TarMap &bigFileInfo, TarMap &fileBackupedInfo, map &smallFiles, uint32_t includesNum, uint32_t excludesNum) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - HILOGI("Start Do backup"); + HILOGI("bigFileInfo size: %{public}zu, fileBackupedInfo size %{public}zu, smallFiles size: %{public}zu", + bigFileInfo.size(), fileBackupedInfo.size(), smallFiles.size()); auto start = std::chrono::system_clock::now(); if (extension_ == nullptr) { HILOGE("Failed to do backup, extension is nullptr"); @@ -798,24 +801,25 @@ int BackupExtExtension::DoBackup(TarMap &bigFileInfo, map &small // 回传大文件 HILOGI("Will notify BigFileReady"); - auto res = BigFileReady(bigFileInfo, proxy); + auto res = BigFileReady(bigFileInfo, proxy, fileBackupedInfo.size()); HILOGI("Start packet Tar files"); // 分片打包, 回传tar包 TarMap tarMap {}; DoPacket(smallFiles, tarMap, proxy); bigFileInfo.insert(tarMap.begin(), tarMap.end()); + fileBackupedInfo.insert(tarMap.begin(), tarMap.end()); HILOGI("Do backup, DoPacket end"); HILOGI("Will notify IndexFileReady"); - if (auto ret = IndexFileReady(bigFileInfo, proxy); ret) { + if (auto ret = IndexFileReady(fileBackupedInfo, proxy); ret) { return ret; } HILOGI("HandleBackup finish, ret = %{public}d", res); auto end = std::chrono::system_clock::now(); auto cost = std::chrono::duration_cast(end - start).count(); - AppRadar::DoBackupInfo doBackupInfo = {cost, bigFileInfo.size(), smallFiles.size(), tarMap.size(), + AppRadar::DoBackupInfo doBackupInfo = {cost, fileBackupedInfo.size(), smallFiles.size(), tarMap.size(), includesNum, excludesNum}; RecordDoBackupRes(bundleName_, res, doBackupInfo); return res; @@ -836,6 +840,7 @@ tuple BackupExtExtension::CalculateDataSize(const B // 扫描文件计算数据量 tie(bigFileInfo, smallFiles) = GetFileInfos(includes, excludes); + ScanFileSingleton::GetInstance().SetCompeletedFlag(true); appStatistic_->smallFileCount_ = smallFiles.size(); appStatistic_->bigFileCount_ = bigFileInfo.size(); for (const auto &item : bigFileInfo) { @@ -1020,32 +1025,7 @@ void BackupExtExtension::AsyncTaskBackup(const string config) auto ptr = obj.promote(); BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have been released"); try { - if (!ptr->StopExtTimer()) { - throw BError(BError::Codes::EXT_TIMER_ERROR, "Failed to stop extTimer"); - } - int64_t totalSize = 0; - TarMap bigFileInfo; - map smallFiles; - BJsonCachedEntity cachedEntity(config); - auto cache = cachedEntity.Structuralize(); - ptr->DoBackupStart(); - auto [err, includeSize, excludeSize] = ptr->CalculateDataSize(cache, totalSize, bigFileInfo, smallFiles); - if (err != ERR_OK) { - throw BError(BError::Codes::EXT_INVAL_ARG, "Failed to mkdir"); - } - if (!ptr->RefreshDataSize(totalSize)) { - throw BError(BError::Codes::EXT_INVAL_ARG, "Failed to RefreshDataSize"); - } - bool isFwkStart; - ptr->StartFwkTimer(isFwkStart); - if (!isFwkStart) { - HILOGE("Do backup, start fwk timer fail."); - throw BError(BError::Codes::EXT_TIMER_ERROR, "Failed to start fwkTimer"); - } - auto ret = ptr->DoBackup(bigFileInfo, smallFiles, includeSize, excludeSize); - ptr->DoBackupEnd(); - ptr->AppDone(ret); - HILOGI("backup app done %{public}d", ret); + ptr->CalculateDataSizeTask(config); } catch (const BError &e) { HILOGE("extension: AsyncTaskBackup error, err code:%{public}d", e.GetCode()); ptr->AppDone(e.GetCode()); @@ -1066,6 +1046,29 @@ void BackupExtExtension::AsyncTaskBackup(const string config) HILOGE("Failed to add task to thread pool"); } }); + + auto dobackupTask = [obj {wptr(this)}, config]() { + auto ptr = obj.promote(); + BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have been released"); + try { + ptr->DoBackUpTask(config); + } catch (const BError &e) { + HILOGE("extension: AsyncTaskBackup error, err code:%{public}d", e.GetCode()); + ptr->AppDone(e.GetCode()); + } catch (...) { + HILOGE("Failed to restore the ext bundle"); + ptr->AppDone(BError(BError::Codes::EXT_INVAL_ARG).GetCode()); + } + ptr->DoClear(); + }; + + threadPool_.AddTask([dobackupTask]() { + try { + dobackupTask(); + } catch (...) { + HILOGE("Failed to add task to thread pool"); + } + }); } void BackupExtExtension::RestoreBigFilesForSpecialCloneCloud(const ExtManageInfo &item) diff --git a/frameworks/native/backup_ext/src/sub_ext_extension.cpp b/frameworks/native/backup_ext/src/sub_ext_extension.cpp index cf9de6eb4b4e9135b8553ccf5f80e5cd07af6dfb..dd8d46e8d3e795fb6208bd085516ad152532082e 100644 --- a/frameworks/native/backup_ext/src/sub_ext_extension.cpp +++ b/frameworks/native/backup_ext/src/sub_ext_extension.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ #include "b_ohos/startup/backup_para.h" #include "b_radar/b_radar.h" #include "b_tarball/b_tarball_factory.h" +#include "b_utils/scan_file_singleton.h" #include "filemgmt_libhilog.h" #include "hitrace_meter.h" #include "sandbox_helper.h" @@ -1467,4 +1469,161 @@ void BackupExtExtension::RmBigFileReportForSpecialCloneCloud(const std::string & } reportHashSrcPathMap_.erase(iter); } + +void BackupExtExtension::CalculateDataSizeTask(const string &config) +{ + if (!StopExtTimer()) { + throw BError(BError::Codes::EXT_TIMER_ERROR, "Failed to stop extTimer"); + } + int64_t totalSize = 0; + TarMap bigFileInfo; + map smallFiles; + BJsonCachedEntity cachedEntity(config); + auto cache = cachedEntity.Structuralize(); + auto [err, includeSize, excludeSize] = CalculateDataSize(cache, totalSize, bigFileInfo, smallFiles); + ScanFileSingleton::GetInstance().SetIncludeSize(includeSize); + ScanFileSingleton::GetInstance().SetExcludeSize(excludeSize); + if (err != ERR_OK) { + throw BError(BError::Codes::EXT_INVAL_ARG, "Failed to mkdir"); + } + if (!RefreshDataSize(totalSize)) { + throw BError(BError::Codes::EXT_INVAL_ARG, "Failed to RefreshDataSize"); + } + bool isFwkStart; + StartFwkTimer(isFwkStart); + if (!isFwkStart) { + HILOGE("Do backup, start fwk timer fail."); + throw BError(BError::Codes::EXT_TIMER_ERROR, "Failed to start fwkTimer"); + } +} + +void BackupExtExtension::DoBackUpTask(const string &config) +{ + BJsonCachedEntity cachedEntity(config); + auto cache = cachedEntity.Structuralize(); + vector excludes = cache.GetExcludes(); + vector endExcludes = excludes; + PreDealExcludes(endExcludes); + + int ret = 0; + TarMap fileBackupedInfo; + while (!ScanFileSingleton::GetInstance().GetCompeletedFlag()) { + ScanFileSingleton::GetInstance().WaitForFiles(); + std::map incFiles = ScanFileSingleton::GetInstance().GetAllBigFiles(); + if (incFiles.empty()) { + continue; + } + map bigFiles = MatchFiles(incFiles, endExcludes); + TarMap bigFileInfo = Transfer2Bigfiles(bigFiles); + ret = DoBackupBigFiles(bigFileInfo, fileBackupedInfo.size()); + fileBackupedInfo.insert(bigFileInfo.begin(), bigFileInfo.end()); + } + + map incSmallFiles = ScanFileSingleton::GetInstance().GetAllSmallFiles(); + map smallFiles = MatchFiles(incSmallFiles, endExcludes); + + std::map incFiles = ScanFileSingleton::GetInstance().GetAllBigFiles(); + map bigFiles = MatchFiles(incFiles, endExcludes); + TarMap bigFileInfo = Transfer2Bigfiles(bigFiles); + uint32_t includeSize = ScanFileSingleton::GetInstance().GetIncludeSize(); + uint32_t excludeSize = ScanFileSingleton::GetInstance().GetExcludeSize(); + + fileBackupedInfo.insert(bigFileInfo.begin(), bigFileInfo.end()); + ret = DoBackup(bigFileInfo, fileBackupedInfo, smallFiles, includeSize, excludeSize); + AppDone(ret); + HILOGI("backup app done %{public}d", ret); +} + +template +std::map BackupExtExtension::MatchFiles(map files, vector endExcludes) +{ + auto isMatch = [](const vector &s, const string &str) -> bool { + if (str.empty() || s.empty()) { + return false; + } + for (const string &item : s) { + if (fnmatch(item.data(), str.data(), FNM_LEADING_DIR) == 0) { + return true; + } + } + return false; + }; + + std::map excludesFiles; + for (const auto &item : files) { + if (!isMatch(endExcludes, item.first)) { + excludesFiles.emplace(item); + } + } + return excludesFiles; +} + +int BackupExtExtension::DoBackupBigFiles(TarMap &bigFileInfo, uint32_t backupedFileSize) +{ + HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); + HILOGI("Start do backup big files, bigFileInfo size: %{public}zu", bigFileInfo.size()); + if (extension_ == nullptr) { + HILOGE("Failed to do backup, extension is nullptr"); + throw BError(BError::Codes::EXT_INVAL_ARG, "Extension is nullptr"); + } + if (extension_->GetExtensionAction() != BConstants::ExtensionAction::BACKUP) { + return EPERM; + } + + auto proxy = ServiceClient::GetInstance(); + if (proxy == nullptr) { + throw BError(BError::Codes::EXT_BROKEN_BACKUP_SA, std::generic_category().message(errno)); + } + + auto res = BigFileReady(bigFileInfo, proxy, backupedFileSize); + HILOGI("HandleBackup finish, ret = %{public}d", res); + return res; +} + +TarMap BackupExtExtension::Transfer2Bigfiles(std::map files) +{ + auto getStringHash = [](const TarMap &m, const string &str) -> string { + ostringstream strHex; + strHex << hex; + + hash strHash; + size_t szHash = strHash(str); + strHex << setfill('0') << setw(BConstants::BIG_FILE_NAME_SIZE) << szHash; + string name = strHex.str(); + for (int i = 0; m.find(name) != m.end(); ++i, strHex.str("")) { + szHash = strHash(str + to_string(i)); + strHex << setfill('0') << setw(BConstants::BIG_FILE_NAME_SIZE) << szHash; + name = strHex.str(); + } + return name; + }; + + TarMap bigFileInfo; + for (const auto& item : files) { + string md5Name = getStringHash(bigFileInfo, item.first); + if (!md5Name.empty()) { + bigFileInfo.emplace(md5Name, make_tuple(item.first, item.second, true)); + } + } + return bigFileInfo; +} + +void BackupExtExtension::PreDealExcludes(std::vector &excludes) +{ + size_t lenEx = excludes.size(); + int j = 0; + for (size_t i = 0; i < lenEx; ++i) { + if (!excludes[i].empty()) { + if (excludes[i].at(excludes[i].size() - 1) == BConstants::FILE_SEPARATOR_CHAR) { + excludes[i] += "*"; + } + if (excludes[i].find(BConstants::FILE_SEPARATOR_CHAR) != string::npos && + excludes[i].at(0) != BConstants::FILE_SEPARATOR_CHAR) { + excludes[i] = BConstants::FILE_SEPARATOR_CHAR + excludes[i]; + } + excludes[j++] = excludes[i]; + } + } + excludes.resize(j); +} } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_ipc/svc_session_manager.cpp b/services/backup_sa/src/module_ipc/svc_session_manager.cpp index 4293b6dc6722f78d676d78baf50d3f7d057b53a3..1d99da63a8aee38f984b6a471a6f9932b241ef95 100644 --- a/services/backup_sa/src/module_ipc/svc_session_manager.cpp +++ b/services/backup_sa/src/module_ipc/svc_session_manager.cpp @@ -886,6 +886,7 @@ void SvcSessionManager::SetBundleDataSize(const std::string &bundleName, int64_t uint32_t SvcSessionManager::CalAppProcessTime(const std::string &bundleName) { const int64_t minTimeout = 900; /* 900 second */ + const int64_t maxTimeout = 1800; /* 18000 second */ const int64_t defaultTimeout = 30; /* 30 second */ const int64_t processRate = 3 * 1024 * 1024; /* 3M/s */ const int64_t multiple = 3; @@ -904,6 +905,7 @@ uint32_t SvcSessionManager::CalAppProcessTime(const std::string &bundleName) /* timeout = (AppSize / 3Ms) * 3 + 30 */ timeout = defaultTimeout + (appSize / processRate) * multiple; timeout = timeout < minTimeout ? minTimeout : timeout; + timeout = timeout > maxTimeout ? maxTimeout : timeout; resTimeoutMs = (uint32_t)(timeout * invertMillisecond % UINT_MAX); /* conver second to millisecond */ HILOGI("Calculate App extension process run timeout=%{public}u(ms), bundleName=%{public}s ", resTimeoutMs, bundleName.c_str()); diff --git a/utils/BUILD.gn b/utils/BUILD.gn index de06ec613278c1204c503d6618f0252e8b3d7e6f..90f31d3e6bfb566bf93605bb864dd832851e7f11 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -83,6 +83,7 @@ ohos_shared_library("backup_utils") { "src/b_tarball/b_tarball_cmdline.cpp", "src/b_tarball/b_tarball_factory.cpp", "src/b_utils/b_time.cpp", + "src/b_utils/scan_file_singleton.cpp", ] configs = [ diff --git a/utils/include/b_resources/b_constants.h b/utils/include/b_resources/b_constants.h index 59ee1ccbf141d5c15adf0a8a763206276cd0e592..030614f1bf6f246fdae148ee724b028773a47cba 100644 --- a/utils/include/b_resources/b_constants.h +++ b/utils/include/b_resources/b_constants.h @@ -53,7 +53,7 @@ constexpr int SYSTEM_UID = 0; constexpr int XTS_UID = 1; constexpr int DEFAULT_USER_ID = 100; constexpr int BACKUP_UID = 1089; -constexpr int EXTENSION_THREAD_POOL_COUNT = 1; +constexpr int EXTENSION_THREAD_POOL_COUNT = 2; constexpr int BACKUP_LOADSA_TIMEOUT_MS = 5000; constexpr int DECIMAL_BASE = 10; // 十进制基数 diff --git a/utils/include/b_utils/scan_file_singleton.h b/utils/include/b_utils/scan_file_singleton.h new file mode 100644 index 0000000000000000000000000000000000000000..b2fefc887e4b723622641fb5da2400c75633ce97 --- /dev/null +++ b/utils/include/b_utils/scan_file_singleton.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_SCAN_FILE_SINGLETON_H +#define OHOS_FILEMGMT_BACKUP_SCAN_FILE_SINGLETON_H + +#include +#include +#include +#include +#include + +namespace OHOS::FileManagement::Backup { +class ScanFileSingleton { +public: + static ScanFileSingleton &GetInstance(); + + void AddBigFile(const std::string& key, const struct stat& value); + + void AddSmallFile(const std::string& key, size_t value); + + std::map GetAllBigFiles(); + + bool GetCompeletedFlag(); + + void SetCompeletedFlag(bool value); + + std::map GetAllSmallFiles(); + + void SetIncludeSize(uint32_t includeSize); + + void SetExcludeSize(uint32_t excludeSize); + + uint32_t GetIncludeSize(); + + uint32_t GetExcludeSize(); + + /** + * @brief 条件等待,等待文件被添加或者扫描完成 + */ + void WaitForFiles(); +private: + // 私有构造函数,防止外部实例化 + ScanFileSingleton() {} + ~ScanFileSingleton() = default; + + std::queue> bigFileQueue_; + std::map smallFiles_; + std::mutex mutexLock_; + std::condition_variable waitForFilesAddCV_; + bool isCalculateCompeleted_ = false; + uint32_t includeSize_ = 0; + uint32_t excludeSize_ = 0; +}; +} // namespace OHOS::FileManagement::ScanFileSingleton +#endif // OHOS_FILEMGMT_BACKUP_SCAN_FILE_SINGLETON_H \ No newline at end of file diff --git a/utils/src/b_filesystem/b_dir.cpp b/utils/src/b_filesystem/b_dir.cpp index 174767445385ba0fddd9ea1d258595e7e11241a8..185d87356eeaa1e210a2d0159b7cacbb028c7127 100644 --- a/utils/src/b_filesystem/b_dir.cpp +++ b/utils/src/b_filesystem/b_dir.cpp @@ -35,6 +35,7 @@ #include "errors.h" #include "filemgmt_libhilog.h" #include "sandbox_helper.h" +#include "b_utils/scan_file_singleton.h" namespace OHOS::FileManagement::Backup { using namespace std; @@ -93,6 +94,12 @@ static uint32_t CheckOverLongPath(const string &path) return len; } +static void InsertSmallFiles(std::map &smallFiles, std::string fileName, size_t size) +{ + ScanFileSingleton::GetInstance().AddSmallFile(fileName, size); + smallFiles.emplace(make_pair(fileName, size)); +} + static tuple, map> GetDirFilesDetail(const string &path, bool recursion, off_t size = -1) @@ -105,7 +112,7 @@ static tuple, map> GetDirFiles if (path.at(path.size()-1) != BConstants::FILE_SEPARATOR_CHAR) { newPath += BConstants::FILE_SEPARATOR_CHAR; } - smallFiles.emplace(make_pair(newPath, 0)); + InsertSmallFiles(smallFiles, newPath, 0); return {ERR_OK, files, smallFiles}; } @@ -126,10 +133,10 @@ static tuple, map> GetDirFiles continue; } if (sta.st_size <= size) { - smallFiles.emplace(make_pair(fileName, sta.st_size)); + InsertSmallFiles(smallFiles, fileName, sta.st_size); continue; } - + ScanFileSingleton::GetInstance().AddBigFile(fileName, sta); files.try_emplace(fileName, sta); continue; } else if (ptr->d_type != DT_DIR) { diff --git a/utils/src/b_utils/scan_file_singleton.cpp b/utils/src/b_utils/scan_file_singleton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a4e403aec99ba389ab903a2d7ffb6d0e3687189 --- /dev/null +++ b/utils/src/b_utils/scan_file_singleton.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "b_utils/scan_file_singleton.h" +#include + +namespace OHOS::FileManagement::Backup { + +// 获取单例实例 +ScanFileSingleton& ScanFileSingleton::GetInstance() +{ + static ScanFileSingleton instance; + return instance; +} + +void ScanFileSingleton::AddBigFile(const std::string& key, const struct stat& value) +{ + std::lock_guard lock(mutexLock_); + bigFileQueue_.push({key, value}); + // 通知等待的线程 + waitForFilesAddCV_.notify_all(); +} + +void ScanFileSingleton::AddSmallFile(const std::string& key, size_t value) +{ + std::lock_guard lock(mutexLock_); + smallFiles_[key] = value; +} + +std::map ScanFileSingleton::GetAllBigFiles() +{ + std::lock_guard lock(mutexLock_); + std::map fileMap; + while (!bigFileQueue_.empty()) { + fileMap[bigFileQueue_.front().first] = bigFileQueue_.front().second; + bigFileQueue_.pop(); + } + return fileMap; +} + +bool ScanFileSingleton::GetCompeletedFlag() +{ + std::lock_guard lock(mutexLock_); + return isCalculateCompeleted_; +} + +void ScanFileSingleton::SetCompeletedFlag(bool value) +{ + std::lock_guard lock(mutexLock_); + isCalculateCompeleted_ = value; + if (value) { + waitForFilesAddCV_.notify_all(); + } +} + +std::map ScanFileSingleton::GetAllSmallFiles() +{ + std::lock_guard lock(mutexLock_); + return smallFiles_; +} + +void ScanFileSingleton::SetIncludeSize(uint32_t includeSize) +{ + std::lock_guard lock(mutexLock_); + includeSize_ = includeSize; +} + +void ScanFileSingleton::SetExcludeSize(uint32_t excludeSize) +{ + std::lock_guard lock(mutexLock_); + excludeSize_ = excludeSize; +} + +uint32_t ScanFileSingleton::GetIncludeSize() +{ + std::lock_guard lock(mutexLock_); + return includeSize_; +} + +uint32_t ScanFileSingleton::GetExcludeSize() +{ + std::lock_guard lock(mutexLock_); + return excludeSize_; +} + +void ScanFileSingleton::WaitForFiles() +{ + std::unique_lock lock(mutexLock_); + HILOGI("calculate is uncompleted, need to wait"); + waitForFilesAddCV_.wait(lock, [this] {return !bigFileQueue_.empty() || isCalculateCompeleted_; }); +} + +} // namespace OHOS::FileManagement::Backup \ No newline at end of file