summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2019-07-29 14:25:27 (GMT)
committerBrad King <brad.king@kitware.com>2019-07-30 14:01:49 (GMT)
commite337e60a50f3de8bb04b91b1233ff60377a9c944 (patch)
tree2de5094f2f25001db6559e2e9be48da62a0415e4
parentd89c0ecf79a791c0b5ffff9fbb59e8720ee88950 (diff)
downloadCMake-e337e60a50f3de8bb04b91b1233ff60377a9c944.zip
CMake-e337e60a50f3de8bb04b91b1233ff60377a9c944.tar.gz
CMake-e337e60a50f3de8bb04b91b1233ff60377a9c944.tar.bz2
fileapi: Compute codemodel compile groups before converting to Json
Previously we converted the description of each source file into its compile group Json object and then used the Json object itself as a unique identifier for the group. When source files have large descriptions their Json objects make inefficient map keys requiring deep comparison operations. Instead use our internal `CompileData` structure as a map key. This enables use of a hash map. Issue: #19520
-rw-r--r--Source/cmFileAPICodemodel.cxx65
1 files changed, 56 insertions, 9 deletions
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 88ddf7e..2a15fd7 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -30,6 +30,9 @@
#include <algorithm>
#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <limits>
#include <map>
#include <memory>
#include <set>
@@ -155,6 +158,10 @@ public:
}
T Value;
JBTIndex Backtrace;
+ friend bool operator==(JBT<T> const& l, JBT<T> const& r)
+ {
+ return l.Value == r.Value && l.Backtrace.Index == r.Backtrace.Index;
+ }
static bool ValueEq(JBT<T> const& l, JBT<T> const& r)
{
return l.Value == r.Value;
@@ -259,6 +266,10 @@ struct CompileData
, IsSystem(isSystem)
{
}
+ friend bool operator==(IncludeEntry const& l, IncludeEntry const& r)
+ {
+ return l.Path == r.Path && l.IsSystem == r.IsSystem;
+ }
};
std::string Language;
@@ -266,8 +277,47 @@ struct CompileData
std::vector<JBT<std::string>> Flags;
std::vector<JBT<std::string>> Defines;
std::vector<IncludeEntry> Includes;
+
+ friend bool operator==(CompileData const& l, CompileData const& r)
+ {
+ return (l.Language == r.Language && l.Sysroot == r.Sysroot &&
+ l.Flags == r.Flags && l.Defines == r.Defines &&
+ l.Includes == r.Includes);
+ }
};
+}
+namespace std {
+
+template <>
+struct hash<CompileData>
+{
+ std::size_t operator()(CompileData const& in) const
+ {
+ using std::hash;
+ size_t result =
+ hash<std::string>()(in.Language) ^ hash<std::string>()(in.Sysroot);
+ for (auto const& i : in.Includes) {
+ result = result ^
+ (hash<std::string>()(i.Path.Value) ^
+ hash<Json::ArrayIndex>()(i.Path.Backtrace.Index) ^
+ (i.IsSystem ? std::numeric_limits<size_t>::max() : 0));
+ }
+ for (auto const& i : in.Flags) {
+ result = result ^ hash<std::string>()(i.Value) ^
+ hash<Json::ArrayIndex>()(i.Backtrace.Index);
+ }
+ for (auto const& i : in.Defines) {
+ result = result ^ hash<std::string>()(i.Value) ^
+ hash<Json::ArrayIndex>()(i.Backtrace.Index);
+ }
+ return result;
+ }
+};
+
+} // namespace std
+
+namespace {
class Target
{
cmGeneratorTarget* GT;
@@ -292,10 +342,10 @@ class Target
struct CompileGroup
{
- std::map<Json::Value, Json::ArrayIndex>::iterator Entry;
+ std::unordered_map<CompileData, Json::ArrayIndex>::iterator Entry;
Json::Value SourceIndexes = Json::arrayValue;
};
- std::map<Json::Value, Json::ArrayIndex> CompileGroupMap;
+ std::unordered_map<CompileData, Json::ArrayIndex> CompileGroupMap;
std::vector<CompileGroup> CompileGroups;
template <typename T>
@@ -864,15 +914,12 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
Json::ArrayIndex Target::AddSourceCompileGroup(cmSourceFile* sf,
Json::ArrayIndex si)
{
- Json::Value compileDataJson =
- this->DumpCompileData(this->BuildCompileData(sf));
- std::map<Json::Value, Json::ArrayIndex>::iterator i =
- this->CompileGroupMap.find(compileDataJson);
+ CompileData compileData = this->BuildCompileData(sf);
+ auto i = this->CompileGroupMap.find(compileData);
if (i == this->CompileGroupMap.end()) {
Json::ArrayIndex cgIndex =
static_cast<Json::ArrayIndex>(this->CompileGroups.size());
- i =
- this->CompileGroupMap.emplace(std::move(compileDataJson), cgIndex).first;
+ i = this->CompileGroupMap.emplace(std::move(compileData), cgIndex).first;
CompileGroup g;
g.Entry = i;
this->CompileGroups.push_back(std::move(g));
@@ -1037,7 +1084,7 @@ Json::Value Target::DumpCompileGroups()
Json::Value Target::DumpCompileGroup(CompileGroup& cg)
{
- Json::Value group = cg.Entry->first;
+ Json::Value group = this->DumpCompileData(cg.Entry->first);
group["sourceIndexes"] = std::move(cg.SourceIndexes);
return group;
}