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.
This commit is contained in:
Brad King 2016-09-26 15:29:53 -04:00
parent 1a5fddfe6d
commit cda8c782db
2 changed files with 27 additions and 6 deletions

View File

@ -1059,6 +1059,7 @@ void cmGlobalGenerator::Configure()
cmMakefile* dirMf = new cmMakefile(this, snapshot); cmMakefile* dirMf = new cmMakefile(this, snapshot);
this->Makefiles.push_back(dirMf); this->Makefiles.push_back(dirMf);
this->IndexMakefile(dirMf);
this->BinaryDirectories.insert( this->BinaryDirectories.insert(
this->CMakeInstance->GetHomeOutputDirectory()); this->CMakeInstance->GetHomeOutputDirectory());
@ -1528,6 +1529,7 @@ void cmGlobalGenerator::ClearGeneratorMembers()
this->TargetDependencies.clear(); this->TargetDependencies.clear();
this->TargetSearchIndex.clear(); this->TargetSearchIndex.clear();
this->GeneratorTargetSearchIndex.clear(); this->GeneratorTargetSearchIndex.clear();
this->MakefileSearchIndex.clear();
this->ProjectMap.clear(); this->ProjectMap.clear();
this->RuleHashes.clear(); this->RuleHashes.clear();
this->DirectoryContentMap.clear(); this->DirectoryContentMap.clear();
@ -1805,6 +1807,7 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
void cmGlobalGenerator::AddMakefile(cmMakefile* mf) void cmGlobalGenerator::AddMakefile(cmMakefile* mf)
{ {
this->Makefiles.push_back(mf); this->Makefiles.push_back(mf);
this->IndexMakefile(mf);
// update progress // update progress
// estimate how many lg there will be // estimate how many lg there will be
@ -1962,12 +1965,9 @@ void cmGlobalGenerator::FillProjectMap()
cmMakefile* cmGlobalGenerator::FindMakefile(const std::string& start_dir) const cmMakefile* cmGlobalGenerator::FindMakefile(const std::string& start_dir) const
{ {
for (std::vector<cmMakefile*>::const_iterator it = this->Makefiles.begin(); MakefileMap::const_iterator i = this->MakefileSearchIndex.find(start_dir);
it != this->Makefiles.end(); ++it) { if (i != this->MakefileSearchIndex.end()) {
std::string sd = (*it)->GetCurrentSourceDirectory(); return i->second;
if (sd == start_dir) {
return *it;
}
} }
return CM_NULLPTR; 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 cmTarget* cmGlobalGenerator::FindTargetImpl(std::string const& name) const
{ {
TargetMap::const_iterator i = this->TargetSearchIndex.find(name); TargetMap::const_iterator i = this->TargetSearchIndex.find(name);

View File

@ -462,13 +462,16 @@ private:
typedef std::unordered_map<std::string, cmTarget*> TargetMap; typedef std::unordered_map<std::string, cmTarget*> TargetMap;
typedef std::unordered_map<std::string, cmGeneratorTarget*> typedef std::unordered_map<std::string, cmGeneratorTarget*>
GeneratorTargetMap; GeneratorTargetMap;
typedef std::unordered_map<std::string, cmMakefile*> MakefileMap;
#else #else
typedef cmsys::hash_map<std::string, cmTarget*> TargetMap; typedef cmsys::hash_map<std::string, cmTarget*> TargetMap;
typedef cmsys::hash_map<std::string, cmGeneratorTarget*> GeneratorTargetMap; typedef cmsys::hash_map<std::string, cmGeneratorTarget*> GeneratorTargetMap;
typedef cmsys::hash_map<std::string, cmMakefile*> MakefileMap;
#endif #endif
#else #else
typedef std::map<std::string, cmTarget*> TargetMap; typedef std::map<std::string, cmTarget*> TargetMap;
typedef std::map<std::string, cmGeneratorTarget*> GeneratorTargetMap; typedef std::map<std::string, cmGeneratorTarget*> GeneratorTargetMap;
typedef std::map<std::string, cmMakefile*> MakefileMap;
#endif #endif
// Map efficiently from target name to cmTarget instance. // Map efficiently from target name to cmTarget instance.
// Do not use this structure for looping over all targets. // Do not use this structure for looping over all targets.
@ -476,6 +479,11 @@ private:
TargetMap TargetSearchIndex; TargetMap TargetSearchIndex;
GeneratorTargetMap GeneratorTargetSearchIndex; 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; cmMakefile* TryCompileOuterMakefile;
// If you add a new map here, make sure it is copied // If you add a new map here, make sure it is copied
// in EnableLanguagesFromGenerator // in EnableLanguagesFromGenerator
@ -528,6 +536,8 @@ private:
void ClearGeneratorMembers(); void ClearGeneratorMembers();
void IndexMakefile(cmMakefile* mf);
virtual const char* GetBuildIgnoreErrorsFlag() const { return CM_NULLPTR; } virtual const char* GetBuildIgnoreErrorsFlag() const { return CM_NULLPTR; }
// Cache directory content and target files to be built. // Cache directory content and target files to be built.