ENH: add caching for the input CMakeList.txt files, 2X speed up

This commit is contained in:
Bill Hoffman 2001-08-28 18:28:31 -04:00
parent 91f27f6fbc
commit 5edd7673e1
7 changed files with 194 additions and 13 deletions

View File

@ -117,6 +117,10 @@ SOURCE=.\cmDSWWriter.cxx
# End Source File
# Begin Source File
SOURCE=.\cmListFileCache.cxx
# End Source File
# Begin Source File
SOURCE=.\cmMakeDepend.cxx
# End Source File
# Begin Source File

View File

@ -24,6 +24,7 @@ cmCustomCommand.cxx
cmCacheManager.cxx
cmCableClassSet.cxx
cmSourceGroup.cxx
cmListFileCache.cxx
)
# configure the .h file

View File

@ -32,9 +32,6 @@ Package=<4>
Begin Project Dependency
Project_Dep_Name ctest
End Project Dependency
Begin Project Dependency
Project_Dep_Name DumpDocumentation
End Project Dependency
}}}
###############################################################################

View File

@ -29,6 +29,7 @@ cmTarget.o \
cmCustomCommand.o \
cmCacheManager.o \
cmCableClassSet.o \
cmListFileCache.o \
cmSourceGroup.o
DEPENDS = $(srcdir)/*.h cmConfigure.h

View File

@ -0,0 +1,86 @@
#include "cmListFileCache.h"
#include "cmSystemTools.h"
cmListFileCache* cmListFileCache::Instance = 0;
cmListFileCache* cmListFileCache::GetInstance()
{
if(!cmListFileCache::Instance)
{
cmListFileCache::Instance = new cmListFileCache;
}
return cmListFileCache::Instance;
}
void cmListFileCache::ClearCache()
{
delete cmListFileCache::Instance;
cmListFileCache::Instance = 0;
}
cmListFile* cmListFileCache::GetFileCache(const char* path)
{
ListFileMap::iterator sl = m_ListFileCache.find(path);
if (sl == m_ListFileCache.end())
{
// if not already in the map, then parse and store the
// file
if(!this->CacheFile(path))
{
return 0;
}
sl = m_ListFileCache.find(path);
if (sl == m_ListFileCache.end())
{
cmSystemTools::Error("Fatal error, in cmListFileCache CacheFile failed",
path);
return 0;
}
}
cmListFile& ret = sl->second;
if(cmSystemTools::ModifiedTime(path) > ret.m_ModifiedTime )
{
if(!this->CacheFile(path))
{
return 0;
}
else
{
sl = m_ListFileCache.find(path);
return &sl->second;
}
}
return &ret;
}
bool cmListFileCache::CacheFile(const char* path)
{
std::ifstream fin(path);
if(!fin)
{
cmSystemTools::Error("error can not open file ", path);
return false;
}
std::string name;
std::vector<std::string> arguments;
cmListFile inFile;
inFile.m_ModifiedTime = cmSystemTools::ModifiedTime(path);
while ( fin )
{
cmListFileFunction inFunction;
if(cmSystemTools::ParseFunction(fin,
inFunction.m_Name,
inFunction.m_Arguments))
{
inFile.m_Functions.push_back(inFunction);
}
}
m_ListFileCache[path] = inFile;
return true;
}

88
Source/cmListFileCache.h Normal file
View File

@ -0,0 +1,88 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2001 Insight Consortium
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the Insight Consortium, nor the names of any consortium members,
nor of any contributors, may be used to endorse or promote products derived
from this software without specific prior written permission.
* Modified source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=========================================================================*/
#ifndef cmListFileCache_h
#define cmListFileCache_h
#include "cmStandardIncludes.h"
/** \class cmListFileCache
* \brief A class to cache list file contents.
*
* cmListFileCache is a class used to cache the contents of parsed
* cmake list files.
*/
struct cmListFileFunction
{
std::string m_Name;
std::vector<std::string> m_Arguments;
};
struct cmListFile
{
long int m_ModifiedTime;
std::vector<cmListFileFunction> m_Functions;
};
class cmListFileCache
{
public:
static cmListFileCache* GetInstance();
static void ClearCache();
/** Return the cached version of the given file.
* If the file is not already in the cache, a cache entry
* will be made. If there is an error loading the file,
* NULL is returned.
*/
cmListFile* GetFileCache(const char* path);
private:
// Cache the file
bool cmListFileCache::CacheFile(const char* path);
// private data
typedef std::map<cmStdString, cmListFile> ListFileMap;
ListFileMap m_ListFileCache; // file name to ListFile map
static cmListFileCache* Instance; // singelton pointer
};
#endif

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "cmCommands.h"
#include "cmCacheManager.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
#include <stdio.h> // required for sprintf
// default is not to be building executables
@ -325,23 +326,26 @@ bool cmMakefile::ReadListFile(const char* filename, const char* external)
filenametoread= external;
}
std::ifstream fin(filenametoread);
if(!fin)
cmListFile* lf =
cmListFileCache::GetInstance()->GetFileCache(filenametoread);
if(!lf)
{
cmSystemTools::Error("error can not open file ", filenametoread);
return false;
}
// add this list file to the list of dependencies
m_ListFiles.push_back( filenametoread);
std::string name;
std::vector<std::string> arguments;
while ( fin )
int numberFunctions = lf->m_Functions.size();
for(int i =0; i < numberFunctions; ++i)
{
// add this list file to the list of dependencies
m_ListFiles.push_back( filenametoread);
if(cmSystemTools::ParseFunction(fin, name, arguments) &&
!this->IsFunctionBlocked(name.c_str(),arguments))
cmListFileFunction& curFunction = lf->m_Functions[i];
if(!this->IsFunctionBlocked(curFunction.m_Name.c_str(),
curFunction.m_Arguments))
{
this->ExecuteCommand(name,arguments);
this->ExecuteCommand(curFunction.m_Name,
curFunction.m_Arguments);
}
}