diff options
author | Brad King <brad.king@kitware.com> | 2019-07-29 14:25:27 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2019-07-30 14:01:49 (GMT) |
commit | e337e60a50f3de8bb04b91b1233ff60377a9c944 (patch) | |
tree | 2de5094f2f25001db6559e2e9be48da62a0415e4 | |
parent | d89c0ecf79a791c0b5ffff9fbb59e8720ee88950 (diff) | |
download | CMake-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.cxx | 65 |
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; } |