From e337e60a50f3de8bb04b91b1233ff60377a9c944 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 29 Jul 2019 10:25:27 -0400 Subject: 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 --- Source/cmFileAPICodemodel.cxx | 65 +++++++++++++++++++++++++++++++++++++------ 1 file 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 #include +#include +#include +#include #include #include #include @@ -155,6 +158,10 @@ public: } T Value; JBTIndex Backtrace; + friend bool operator==(JBT const& l, JBT const& r) + { + return l.Value == r.Value && l.Backtrace.Index == r.Backtrace.Index; + } static bool ValueEq(JBT const& l, JBT 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> Flags; std::vector> Defines; std::vector 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 +{ + std::size_t operator()(CompileData const& in) const + { + using std::hash; + size_t result = + hash()(in.Language) ^ hash()(in.Sysroot); + for (auto const& i : in.Includes) { + result = result ^ + (hash()(i.Path.Value) ^ + hash()(i.Path.Backtrace.Index) ^ + (i.IsSystem ? std::numeric_limits::max() : 0)); + } + for (auto const& i : in.Flags) { + result = result ^ hash()(i.Value) ^ + hash()(i.Backtrace.Index); + } + for (auto const& i : in.Defines) { + result = result ^ hash()(i.Value) ^ + hash()(i.Backtrace.Index); + } + return result; + } +}; + +} // namespace std + +namespace { class Target { cmGeneratorTarget* GT; @@ -292,10 +342,10 @@ class Target struct CompileGroup { - std::map::iterator Entry; + std::unordered_map::iterator Entry; Json::Value SourceIndexes = Json::arrayValue; }; - std::map CompileGroupMap; + std::unordered_map CompileGroupMap; std::vector CompileGroups; template @@ -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::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(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; } -- cgit v0.12