#include #include "pch.h" #include "FileDiff.h" #include "IEngine.h" using namespace craftlab::fakeraid; FileDiff::FileDiff() { } FileDiff::~FileDiff() { } FileDiff::FileVersionList FileDiff::GroupBy(const IEngine& engine, const FileAndSumListByRepositoryIndex& fileListsWithRepo, size_t indexCount) { FileVersionList result; for (const FileAndSumList& fileLists : fileListsWithRepo.FileAndSumListByRepositoryIndex) { for (const FileAndSum& i : fileLists) { const std::string fullPath = engine.BuildCurrentDirPath(i); if (!result.contains(fullPath)) result.emplace(fullPath, std::vector>(indexCount, std::nullopt)); result[fullPath][i.repositoryIndex] = i; } } return result; } std::vector FileDiff::computeVersionIds(const ListOfOptionalFileAndSum& versions) { std::vector result; std::map versionList; for (const OptionalFileAndSum& version : versions) { if (version.has_value()) { if (versionList.contains(version->checksum)) result.push_back(versionList[version->checksum]); else { int nextId = (int) versionList.size() + 1; versionList.emplace(version->checksum, nextId); result.push_back(nextId); } } else result.push_back(0); } return result; } void FileDiff::CheckVersions(DiffResult& output, const std::string& fileKey, const FileDiff::ListOfOptionalFileAndSum& versions) { const auto& firstVersionIter = std::find_if(versions.begin(), versions.end(), [](const OptionalFileAndSum& i) { return i.has_value(); }); const FileAndSum& firstVersion = firstVersionIter->value(); std::vector filePresent(versions.size(), true); int idx =0; for (const OptionalFileAndSum& i : versions) { if (!i.has_value()) { filePresent[idx] = false; continue; } if (firstVersion.checksum != i->checksum) { output.differentFiles.emplace(fileKey, computeVersionIds(versions)); return; } } if (std::find(filePresent.begin(), filePresent.end(), false) != filePresent.end()) { if (firstVersion.isDir) output.missingDirs.emplace(fileKey, filePresent); else output.missingFiles.emplace(fileKey, filePresent); } else output.correctFiles.push_back(firstVersion); } DiffResult FileDiff::Process(const IEngine& engine, const FileAndSumListByRepositoryIndex& fileLists) { DiffResult result; const FileVersionList& fileAndVersionLists = GroupBy(engine, fileLists, engine.GetRootPaths().size()); for (const std::pair& key : fileAndVersionLists) CheckVersions(result, key.first, key.second); result.FileList = fileLists.FileList; return result; } bool DiffResult::HasError() const { return !differentFiles.empty() || !missingDirs.empty() || !missingFiles.empty(); } size_t FileAndSumListByRepositoryIndex::ExistingFileCount() const { size_t result {}; for (const auto& i : FileAndSumListByRepositoryIndex) result += i.size(); return result; }