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.
This commit is contained in:
Brad King 2009-01-05 15:00:57 -05:00
parent b5f3d4be61
commit ed3bb743f4
5 changed files with 32 additions and 55 deletions

View File

@ -328,16 +328,10 @@ bool cmGetPropertyCommand::HandleTestMode()
} }
// Loop over all tests looking for matching names. // Loop over all tests looking for matching names.
std::vector<cmTest*> const& tests = *this->Makefile->GetTests(); if(cmTest* test = this->Makefile->GetTest(this->Name.c_str()))
for(std::vector<cmTest*>::const_iterator ti = tests.begin();
ti != tests.end(); ++ti)
{
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. // If not found it is an error.
cmOStringStream e; cmOStringStream e;

View File

@ -108,6 +108,7 @@ cmMakefile::cmMakefile(const cmMakefile& mf)
this->Targets = mf.Targets; this->Targets = mf.Targets;
this->SourceFiles = mf.SourceFiles; this->SourceFiles = mf.SourceFiles;
this->Tests = mf.Tests; this->Tests = mf.Tests;
this->OrderedTests = mf.OrderedTests;
this->IncludeDirectories = mf.IncludeDirectories; this->IncludeDirectories = mf.IncludeDirectories;
this->LinkDirectories = mf.LinkDirectories; this->LinkDirectories = mf.LinkDirectories;
this->SystemIncludeDirectories = mf.SystemIncludeDirectories; this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
@ -182,10 +183,10 @@ cmMakefile::~cmMakefile()
{ {
delete *i; delete *i;
} }
for(std::vector<cmTest*>::iterator i = this->Tests.begin(); for(std::map<cmStdString, cmTest*>::iterator i = this->Tests.begin();
i != this->Tests.end(); ++i) i != this->Tests.end(); ++i)
{ {
delete *i; delete i->second;
} }
for(std::vector<cmTarget*>::iterator for(std::vector<cmTarget*>::iterator
i = this->ImportedTargetsOwned.begin(); i = this->ImportedTargetsOwned.begin();
@ -3117,6 +3118,7 @@ cmTarget* cmMakefile::FindTarget(const char* name)
return 0; return 0;
} }
//----------------------------------------------------------------------------
cmTest* cmMakefile::CreateTest(const char* testName) cmTest* cmMakefile::CreateTest(const char* testName)
{ {
if ( !testName ) if ( !testName )
@ -3131,35 +3133,30 @@ cmTest* cmMakefile::CreateTest(const char* testName)
test = new cmTest; test = new cmTest;
test->SetName(testName); test->SetName(testName);
test->SetMakefile(this); test->SetMakefile(this);
this->Tests.push_back(test); this->Tests[testName] = test;
this->OrderedTests.push_back(test);
return test; return test;
} }
//----------------------------------------------------------------------------
cmTest* cmMakefile::GetTest(const char* testName) const cmTest* cmMakefile::GetTest(const char* testName) const
{ {
if ( !testName ) if(testName)
{ {
return 0; std::map<cmStdString, cmTest*>::const_iterator
} mi = this->Tests.find(testName);
std::vector<cmTest*>::const_iterator it; if(mi != this->Tests.end())
for ( it = this->Tests.begin(); it != this->Tests.end(); ++ it )
{ {
if ( strcmp((*it)->GetName(), testName) == 0 ) return mi->second;
{
return *it;
} }
} }
return 0; return 0;
} }
//----------------------------------------------------------------------------
const std::vector<cmTest*> *cmMakefile::GetTests() const const std::vector<cmTest*> *cmMakefile::GetTests() const
{ {
return &this->Tests; return &this->OrderedTests;
}
std::vector<cmTest*> *cmMakefile::GetTests()
{
return &this->Tests;
} }
std::string cmMakefile::GetListFileStack() std::string cmMakefile::GetListFileStack()

View File

@ -737,7 +737,6 @@ public:
*/ */
cmTest* GetTest(const char* testName) const; cmTest* GetTest(const char* testName) const;
const std::vector<cmTest*> *GetTests() const; const std::vector<cmTest*> *GetTests() const;
std::vector<cmTest*> *GetTests();
/** /**
* Get a list of macros as a ; separated string * Get a list of macros as a ; separated string
@ -807,7 +806,8 @@ protected:
std::vector<cmSourceFile*> SourceFiles; std::vector<cmSourceFile*> SourceFiles;
// Tests // Tests
std::vector<cmTest*> Tests; std::map<cmStdString, cmTest*> Tests;
std::vector<cmTest*> OrderedTests;
// The include and link-library paths. These may have order // The include and link-library paths. These may have order
// dependency, so they must be vectors (not set). // dependency, so they must be vectors (not set).

View File

@ -327,15 +327,14 @@ bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTestMode() bool cmSetPropertyCommand::HandleTestMode()
{ {
// Loop over all tests looking for matching names. // Look for tests with all names given.
std::vector<cmTest*> const& tests = *this->Makefile->GetTests(); std::set<cmStdString>::iterator next;
for(std::vector<cmTest*>::const_iterator ti = tests.begin(); for(std::set<cmStdString>::iterator ni = this->Names.begin();
ti != tests.end(); ++ti) ni != this->Names.end(); ni = next)
{ {
cmTest* test = *ti; next = ni;
std::set<cmStdString>::iterator ni = ++next;
this->Names.find(test->GetName()); if(cmTest* test = this->Makefile->GetTest(ni->c_str()))
if(ni != this->Names.end())
{ {
if(this->HandleTest(test)) if(this->HandleTest(test))
{ {

View File

@ -100,30 +100,17 @@ bool cmSetTestsPropertiesCommand
std::vector<std::string> &propertyPairs, std::vector<std::string> &propertyPairs,
cmMakefile *mf, std::string &errors) cmMakefile *mf, std::string &errors)
{ {
std::vector<cmTest*> &tests = *mf->GetTests(); if(cmTest* test = mf->GetTest(tname))
// 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<cmTest*>::iterator it;
for ( it = tests.begin(); it != tests.end(); ++ it )
{
cmTest* test = *it;
if ( !strcmp(test->GetName(),tname ))
{ {
// now loop through all the props and set them // now loop through all the props and set them
unsigned int k;
for (k = 0; k < propertyPairs.size(); k = k + 2) for (k = 0; k < propertyPairs.size(); k = k + 2)
{ {
test->SetProperty(propertyPairs[k].c_str(), test->SetProperty(propertyPairs[k].c_str(),
propertyPairs[k+1].c_str()); propertyPairs[k+1].c_str());
} }
found = true;
break;
} }
} else
// if file is not already in the makefile, then add it
if ( ! found )
{ {
errors = "Can not find test to add properties to: "; errors = "Can not find test to add properties to: ";
errors += tname; errors += tname;