From cda8c782db80a1352ec6737b783558e35238bf17 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 26 Sep 2016 15:29:53 -0400 Subject: cmGlobalGenerator: Optimize FindMakefile method with an index This method is used by directory get/set APIs. With the new `SUBDIRECTORIES` and `BUILDSYSTEM_TARGETS` methods projects may now make heavy use of these APIs to traverse their directory structure and process targets. Make this faster by indexing the directory lookups. --- Source/cmGlobalGenerator.cxx | 23 +++++++++++++++++------ Source/cmGlobalGenerator.h | 10 ++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 95747f2..4c62be7 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1059,6 +1059,7 @@ void cmGlobalGenerator::Configure() cmMakefile* dirMf = new cmMakefile(this, snapshot); this->Makefiles.push_back(dirMf); + this->IndexMakefile(dirMf); this->BinaryDirectories.insert( this->CMakeInstance->GetHomeOutputDirectory()); @@ -1528,6 +1529,7 @@ void cmGlobalGenerator::ClearGeneratorMembers() this->TargetDependencies.clear(); this->TargetSearchIndex.clear(); this->GeneratorTargetSearchIndex.clear(); + this->MakefileSearchIndex.clear(); this->ProjectMap.clear(); this->RuleHashes.clear(); this->DirectoryContentMap.clear(); @@ -1805,6 +1807,7 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand( void cmGlobalGenerator::AddMakefile(cmMakefile* mf) { this->Makefiles.push_back(mf); + this->IndexMakefile(mf); // update progress // estimate how many lg there will be @@ -1962,12 +1965,9 @@ void cmGlobalGenerator::FillProjectMap() cmMakefile* cmGlobalGenerator::FindMakefile(const std::string& start_dir) const { - for (std::vector::const_iterator it = this->Makefiles.begin(); - it != this->Makefiles.end(); ++it) { - std::string sd = (*it)->GetCurrentSourceDirectory(); - if (sd == start_dir) { - return *it; - } + MakefileMap::const_iterator i = this->MakefileSearchIndex.find(start_dir); + if (i != this->MakefileSearchIndex.end()) { + return i->second; } return CM_NULLPTR; } @@ -2012,6 +2012,17 @@ void cmGlobalGenerator::IndexGeneratorTarget(cmGeneratorTarget* gt) } } +void cmGlobalGenerator::IndexMakefile(cmMakefile* mf) +{ + // FIXME: add_subdirectory supports multiple build directories + // sharing the same source directory. We currently index only the + // first one, because that is what FindMakefile has always returned. + // All of its callers will need to be modified to support looking + // up directories by build directory path. + this->MakefileSearchIndex.insert( + MakefileMap::value_type(mf->GetCurrentSourceDirectory(), mf)); +} + cmTarget* cmGlobalGenerator::FindTargetImpl(std::string const& name) const { TargetMap::const_iterator i = this->TargetSearchIndex.find(name); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 7bc389d..8f1d70c 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -462,13 +462,16 @@ private: typedef std::unordered_map TargetMap; typedef std::unordered_map GeneratorTargetMap; + typedef std::unordered_map MakefileMap; #else typedef cmsys::hash_map TargetMap; typedef cmsys::hash_map GeneratorTargetMap; + typedef cmsys::hash_map MakefileMap; #endif #else typedef std::map TargetMap; typedef std::map GeneratorTargetMap; + typedef std::map MakefileMap; #endif // Map efficiently from target name to cmTarget instance. // Do not use this structure for looping over all targets. @@ -476,6 +479,11 @@ private: TargetMap TargetSearchIndex; GeneratorTargetMap GeneratorTargetSearchIndex; + // Map efficiently from source directory path to cmMakefile instance. + // Do not use this structure for looping over all directories. + // It may not contain all of them (see note in IndexMakefile method). + MakefileMap MakefileSearchIndex; + cmMakefile* TryCompileOuterMakefile; // If you add a new map here, make sure it is copied // in EnableLanguagesFromGenerator @@ -528,6 +536,8 @@ private: void ClearGeneratorMembers(); + void IndexMakefile(cmMakefile* mf); + virtual const char* GetBuildIgnoreErrorsFlag() const { return CM_NULLPTR; } // Cache directory content and target files to be built. -- cgit v0.12