From ed3bb743f4c2687187e1721c5ccc64dd06cc3db5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 5 Jan 2009 15:00:57 -0500 Subject: ENH: Improve test property speed with a map Previously we stored a vector of tests to preserve their order. Property set/get operations would do a linear search for matching tests. This uses a map to efficiently look up tests while keeping the original order with a vector for test file generation. --- Source/cmGetPropertyCommand.cxx | 10 ++-------- Source/cmMakefile.cxx | 31 ++++++++++++++----------------- Source/cmMakefile.h | 4 ++-- Source/cmSetPropertyCommand.cxx | 17 ++++++++--------- Source/cmSetTestsPropertiesCommand.cxx | 27 +++++++-------------------- 5 files changed, 33 insertions(+), 56 deletions(-) diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index c110161..93c724a 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -328,15 +328,9 @@ bool cmGetPropertyCommand::HandleTestMode() } // Loop over all tests looking for matching names. - std::vector const& tests = *this->Makefile->GetTests(); - for(std::vector::const_iterator ti = tests.begin(); - ti != tests.end(); ++ti) + if(cmTest* test = this->Makefile->GetTest(this->Name.c_str())) { - cmTest* test = *ti; - if(test->GetName() == this->Name) - { - return this->StoreResult(test->GetProperty(this->PropertyName.c_str())); - } + return this->StoreResult(test->GetProperty(this->PropertyName.c_str())); } // If not found it is an error. diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 424ca00..7442318 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -108,6 +108,7 @@ cmMakefile::cmMakefile(const cmMakefile& mf) this->Targets = mf.Targets; this->SourceFiles = mf.SourceFiles; this->Tests = mf.Tests; + this->OrderedTests = mf.OrderedTests; this->IncludeDirectories = mf.IncludeDirectories; this->LinkDirectories = mf.LinkDirectories; this->SystemIncludeDirectories = mf.SystemIncludeDirectories; @@ -182,10 +183,10 @@ cmMakefile::~cmMakefile() { delete *i; } - for(std::vector::iterator i = this->Tests.begin(); + for(std::map::iterator i = this->Tests.begin(); i != this->Tests.end(); ++i) { - delete *i; + delete i->second; } for(std::vector::iterator i = this->ImportedTargetsOwned.begin(); @@ -3117,6 +3118,7 @@ cmTarget* cmMakefile::FindTarget(const char* name) return 0; } +//---------------------------------------------------------------------------- cmTest* cmMakefile::CreateTest(const char* testName) { if ( !testName ) @@ -3131,35 +3133,30 @@ cmTest* cmMakefile::CreateTest(const char* testName) test = new cmTest; test->SetName(testName); test->SetMakefile(this); - this->Tests.push_back(test); + this->Tests[testName] = test; + this->OrderedTests.push_back(test); return test; } +//---------------------------------------------------------------------------- cmTest* cmMakefile::GetTest(const char* testName) const { - if ( !testName ) + if(testName) { - return 0; - } - std::vector::const_iterator it; - for ( it = this->Tests.begin(); it != this->Tests.end(); ++ it ) - { - if ( strcmp((*it)->GetName(), testName) == 0 ) + std::map::const_iterator + mi = this->Tests.find(testName); + if(mi != this->Tests.end()) { - return *it; + return mi->second; } } return 0; } +//---------------------------------------------------------------------------- const std::vector *cmMakefile::GetTests() const { - return &this->Tests; -} - -std::vector *cmMakefile::GetTests() -{ - return &this->Tests; + return &this->OrderedTests; } std::string cmMakefile::GetListFileStack() diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 5a12d2e..c0e0bf4 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -737,7 +737,6 @@ public: */ cmTest* GetTest(const char* testName) const; const std::vector *GetTests() const; - std::vector *GetTests(); /** * Get a list of macros as a ; separated string @@ -807,7 +806,8 @@ protected: std::vector SourceFiles; // Tests - std::vector Tests; + std::map Tests; + std::vector OrderedTests; // The include and link-library paths. These may have order // dependency, so they must be vectors (not set). diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 9d00e32..b683fe7 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -327,15 +327,14 @@ bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf) //---------------------------------------------------------------------------- bool cmSetPropertyCommand::HandleTestMode() { - // Loop over all tests looking for matching names. - std::vector const& tests = *this->Makefile->GetTests(); - for(std::vector::const_iterator ti = tests.begin(); - ti != tests.end(); ++ti) - { - cmTest* test = *ti; - std::set::iterator ni = - this->Names.find(test->GetName()); - if(ni != this->Names.end()) + // Look for tests with all names given. + std::set::iterator next; + for(std::set::iterator ni = this->Names.begin(); + ni != this->Names.end(); ni = next) + { + next = ni; + ++next; + if(cmTest* test = this->Makefile->GetTest(ni->c_str())) { if(this->HandleTest(test)) { diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index 8a849b3..cfb4a85 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -100,30 +100,17 @@ bool cmSetTestsPropertiesCommand std::vector &propertyPairs, cmMakefile *mf, std::string &errors) { - std::vector &tests = *mf->GetTests(); - // now loop over all the targets - unsigned int k; - bool found = false; - // if the file is already in the makefile just set properites on it - std::vector::iterator it; - for ( it = tests.begin(); it != tests.end(); ++ it ) + if(cmTest* test = mf->GetTest(tname)) { - cmTest* test = *it; - if ( !strcmp(test->GetName(),tname )) + // now loop through all the props and set them + unsigned int k; + for (k = 0; k < propertyPairs.size(); k = k + 2) { - // now loop through all the props and set them - for (k = 0; k < propertyPairs.size(); k = k + 2) - { - test->SetProperty(propertyPairs[k].c_str(), - propertyPairs[k+1].c_str()); - } - found = true; - break; + test->SetProperty(propertyPairs[k].c_str(), + propertyPairs[k+1].c_str()); } } - - // if file is not already in the makefile, then add it - if ( ! found ) + else { errors = "Can not find test to add properties to: "; errors += tname; -- cgit v0.12