Skip to content

Commit 76620cf

Browse files
authored
[projmgr] Improve performance of yml file content comparison
1 parent 1c775a0 commit 76620cf

File tree

5 files changed

+50
-21
lines changed

5 files changed

+50
-21
lines changed

tools/projmgr/include/ProjMgrUtils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,13 @@ class ProjMgrUtils {
295295
*/
296296
static const std::string FileTypeFromExtension(const std::string& file);
297297

298+
/**
299+
* @brief normalize line endings for consistent string comparison
300+
* @param input string
301+
* @return output normalized string
302+
*/
303+
static const std::string NormalizeLineEndings(const std::string& in);
304+
298305
protected:
299306
/**
300307
* @brief get filtered list of contexts

tools/projmgr/include/ProjMgrYamlEmitter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020-2024 Arm Limited. All rights reserved.
2+
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -114,6 +114,7 @@ class ProjMgrYamlEmitter {
114114
bool CompareFile(const std::string& filename, const YAML::Node& rootNode);
115115
bool CompareNodes(const YAML::Node& lhs, const YAML::Node& rhs);
116116
bool NeedRebuild(const std::string& filename, const YAML::Node& rootNode);
117+
std::string EraseGeneratedByNode(const std::string& inStr);
117118
};
118119

119120
#endif // PROJMGRYAMLEMITTER_H

tools/projmgr/src/ProjMgrUtils.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
2+
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -464,3 +464,16 @@ const string ProjMgrUtils::FileTypeFromExtension(const string& file) {
464464
}
465465
return RteUtils::EMPTY_STRING;
466466
}
467+
468+
const std::string ProjMgrUtils::NormalizeLineEndings(const std::string& in) {
469+
string out = in;
470+
size_t pos = 0;
471+
while ((pos = out.find("\r\n", pos)) != std::string::npos) {
472+
out.replace(pos++, 2, "\n");
473+
}
474+
pos = 0;
475+
while ((pos = out.find("\r", pos)) != std::string::npos) {
476+
out.replace(pos, 1, "\n");
477+
}
478+
return out;
479+
}

tools/projmgr/src/ProjMgrYamlEmitter.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,29 +87,29 @@ bool ProjMgrYamlEmitter::WriteFile(YAML::Node& rootNode, const std::string& file
8787
return true;
8888
}
8989

90+
string ProjMgrYamlEmitter::EraseGeneratedByNode(const string& inStr) {
91+
size_t startIndex, endIndex;
92+
string outStr = inStr;
93+
startIndex = outStr.find(YAML_GENERATED_BY, 0);
94+
endIndex = outStr.find('\n', startIndex);
95+
if (startIndex != std::string::npos && endIndex != std::string::npos) {
96+
outStr = outStr.erase(startIndex, endIndex - startIndex);
97+
}
98+
return outStr;
99+
};
100+
90101
bool ProjMgrYamlEmitter::CompareFile(const string& filename, const YAML::Node& rootNode) {
91-
if (!RteFsUtils::Exists(filename)) {
102+
string inBuffer;
103+
if (!RteFsUtils::Exists(filename) || !RteFsUtils::ReadFile(filename, inBuffer)) {
92104
return false;
93105
}
94-
const YAML::Node& yamlRoot = YAML::LoadFile(filename);
95-
96-
// emit and load rootNode to ensure both comparison sides have the same formatting
97106
YAML::Emitter emitter;
98-
return CompareNodes(yamlRoot, YAML::Load((emitter << rootNode).c_str()));
107+
const auto& outBuffer = string((emitter << rootNode).c_str()) + '\n';
108+
return ProjMgrUtils::NormalizeLineEndings(EraseGeneratedByNode(inBuffer)) ==
109+
ProjMgrUtils::NormalizeLineEndings(EraseGeneratedByNode(outBuffer));
99110
}
100111

101112
bool ProjMgrYamlEmitter::CompareNodes(const YAML::Node& lhs, const YAML::Node& rhs) {
102-
auto eraseGenNode = [](const string& inStr) {
103-
size_t startIndex, endIndex;
104-
string outStr = inStr;
105-
startIndex = outStr.find(YAML_GENERATED_BY, 0);
106-
endIndex = outStr.find('\n', startIndex);
107-
if (startIndex != std::string::npos && endIndex != std::string::npos) {
108-
outStr = outStr.erase(startIndex, endIndex - startIndex);
109-
}
110-
return outStr;
111-
};
112-
113113
YAML::Emitter lhsEmitter, rhsEmitter;
114114
string lhsData, rhsData;
115115

@@ -118,8 +118,8 @@ bool ProjMgrYamlEmitter::CompareNodes(const YAML::Node& lhs, const YAML::Node& r
118118
rhsEmitter << rhs;
119119

120120
// remove generated-by node from the string
121-
lhsData = eraseGenNode(lhsEmitter.c_str());
122-
rhsData = eraseGenNode(rhsEmitter.c_str());
121+
lhsData = EraseGeneratedByNode(lhsEmitter.c_str());
122+
rhsData = EraseGeneratedByNode(rhsEmitter.c_str());
123123

124124
return (lhsData == rhsData) ? true : false;
125125
}

tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020-2024 Arm Limited. All rights reserved.
2+
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -531,3 +531,11 @@ TEST_F(ProjMgrUtilsUnitTests, ULLToHex) {
531531
EXPECT_EQ("0xDEADBEEF", ProjMgrUtils::ULLToHex(3735928559));
532532
EXPECT_EQ("0xFFFFFFFF", ProjMgrUtils::ULLToHex(4294967295));
533533
}
534+
535+
TEST_F(ProjMgrUtilsUnitTests, NormalizeLineEndings) {
536+
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\r\ndef\r\n"));
537+
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\rdef\r"));
538+
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\rdef\n"));
539+
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\ndef\r"));
540+
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\ndef\n"));
541+
}

0 commit comments

Comments
 (0)