try to refactor the 'is_modified( includefile )' code

felipesanches-svg
Don Bright 2013-05-19 23:31:18 -05:00
parent 77a598ab72
commit 8a83e334ab
6 changed files with 50 additions and 41 deletions

View File

@ -14,35 +14,26 @@
#include <time.h>
#include <sys/stat.h>
//#include "parsersettings.h"
/*!
FIXME: Implement an LRU scheme to avoid having an ever-growing module cache
*/
ModuleCache *ModuleCache::inst = NULL;
#include <iostream>
static bool is_modified(const std::string &filename, const time_t &mtime)
{
std::cout << "cache ismod " << filename << "\n";
struct stat st;
memset(&st, 0, sizeof(struct stat));
stat(filename.c_str(), &st);
return (st.st_mtime > mtime);
}
FileModule *ModuleCache::evaluate(const std::string &filename)
{
std::cout << "modcache eval" << filename << "\n";
FileModule *lib_mod = NULL;
// Create cache ID
// Create cache ID
struct stat st;
memset(&st, 0, sizeof(struct stat));
stat(filename.c_str(), &st);
std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size);
// Lookup in cache
// Lookup in cache
if (this->entries.find(filename) != this->entries.end() &&
this->entries[filename].cache_id == cache_id) {
#ifdef DEBUG
@ -51,15 +42,15 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
#endif
lib_mod = &(*this->entries[filename].module);
BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, lib_mod->includes) {
if (is_modified(item.first, item.second)) {
BOOST_FOREACH(const FileModule::IncludeContainer::value_type &include, lib_mod->includes) {
if (lib_mod->include_modified(include.second)) {
lib_mod = NULL;
break;
}
}
}
// If cache lookup failed (non-existing or old timestamp), compile module
// If cache lookup failed (non-existing or old timestamp), compile module
if (!lib_mod) {
#ifdef DEBUG
if (this->entries.find(filename) != this->entries.end()) {
@ -94,7 +85,7 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
if (lib_mod) {
// We defer deletion so we can ensure that the new module won't
// have the same address as the old
// have the same address as the old
delete oldmodule;
this->entries[filename].module = lib_mod;
} else {

View File

@ -64,6 +64,7 @@ AbstractFunction::~AbstractFunction()
Value AbstractFunction::evaluate(const Context*, const EvalContext *evalctx) const
{
(void)evalctx; // unusued parameter
return Value();
}
@ -500,6 +501,7 @@ Value builtin_search(const Context *, const EvalContext *evalctx)
Value builtin_version(const Context *, const EvalContext *evalctx)
{
(void)evalctx; // unusued parameter
Value::VectorType val;
val.push_back(Value(double(OPENSCAD_YEAR)));
val.push_back(Value(double(OPENSCAD_MONTH)));

View File

@ -204,6 +204,8 @@ void includefile()
PRINTB("lex includefile openfilename: %s",of);
}
rootmodule->registerInclude(filename);
fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames );
if ( fullpath.empty() ) {
PRINTB("WARNING: Can't open 'include' file '%s'.", filename);
@ -227,8 +229,6 @@ void includefile()
return;
}
rootmodule->registerInclude(fullname);
openfiles.push_back(yyin);
openfilenames.push_back(fullname);
filename.clear();

View File

@ -615,7 +615,9 @@ void MainWindow::refreshDocument()
*/
bool MainWindow::compile(bool reload, bool procevents)
{
PRINT("compile");
if (!compileTopLevelDocument(reload)) return false;
PRINT("init render");
// Invalidate renderers before we kill the CSG tree
this->qglview->setRenderer(NULL);
@ -1018,29 +1020,18 @@ bool MainWindow::fileChangedOnDisk()
return false;
}
// FIXME: The following two methods are duplicated in ModuleCache.cc - refactor
static bool is_modified(const std::string &filename, const time_t &mtime)
{
bool modified = false;
struct stat st;
memset(&st, 0, sizeof(struct stat));
bool success = stat(filename.c_str(), &st)==0;
std::cout <<"success" << success << ":" << filename << "\n";
if (success) modified = st.st_mtime > mtime;
else modified = true;
return modified;
}
#include <iostream>
bool MainWindow::includesChanged()
{
PRINT("includes changed?");
if (this->root_module) {
BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) {
std::cout<< item.first << "second" << item.second << "\n";
std::cout<< (is_modified(item.first, item.second)) <<"\n";
if (is_modified(item.first, item.second)) return true;
//std::cout<< item.first << "second" << item.second << "\n";
//std::cout<< (is_modified(item.first, item.second)) <<"\n";
if (this->root_module.include_modified(item))
return true;
}
}
PRINT("includes not changed");
return false;
}
@ -1053,6 +1044,7 @@ bool MainWindow::includesChanged()
*/
bool MainWindow::compileTopLevelDocument(bool reload)
{
PRINT("compile top level");
bool shouldcompiletoplevel = !reload;
if (includesChanged()) shouldcompiletoplevel = true;
@ -1063,6 +1055,7 @@ bool MainWindow::compileTopLevelDocument(bool reload)
}
if (shouldcompiletoplevel) {
PRINT("shouldcompile top level");
console->clear();
updateTemporalVariables();

View File

@ -46,6 +46,8 @@ AbstractModule::~AbstractModule()
AbstractNode *AbstractModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
{
(void)ctx; // avoid unusued parameter warning
AbstractNode *node = new AbstractNode(inst);
node->children = inst->instantiateChildren(evalctx);
@ -194,14 +196,14 @@ std::string Module::dump(const std::string &indent, const std::string &name) con
return dump.str();
}
#include <iostream>
void FileModule::registerInclude(const std::string &filename)
{
std::cout << "reginclude" << filename << "\n";
PRINTB("filemodule reginclude %s", filename);
struct stat st;
memset(&st, 0, sizeof(struct stat));
stat(filename.c_str(), &st);
this->includes[filename] = st.st_mtime;
bool valid = stat(filename.c_str(), &st);
IncludeFile inc = {filename,valid,st.st_mtime};
this->includes[filename] = inc;
}
/*!
@ -252,3 +254,15 @@ AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiat
return node;
}
bool FileModule::include_modified(IncludeFile inc)
{
struct stat st;
memset(&st, 0, sizeof(struct stat));
// todo - search paths
bool valid = stat(inc.filename.c_str(), &st);
if (inc.valid != valid) return true;
if (st.st_mtime > inc.mtime) return true;
return false;
}

View File

@ -5,6 +5,9 @@
#include <vector>
#include <list>
#include <boost/unordered_map.hpp>
#include <time.h>
#include <sys/stat.h>
#include "value.h"
#include "typedefs.h"
#include "localscope.h"
@ -74,6 +77,12 @@ public:
LocalScope scope;
};
struct IncludeFile {
std::string filename;
bool valid;
time_t mtime;
};
// FIXME: A FileModule doesn't have definition arguments, so we shouldn't really
// inherit from a Module
class FileModule : public Module
@ -90,9 +99,9 @@ public:
typedef boost::unordered_map<std::string, class FileModule*> ModuleContainer;
ModuleContainer usedlibs;
typedef boost::unordered_map<std::string, time_t> IncludeContainer;
typedef boost::unordered_map<std::string, struct IncludeFile> IncludeContainer;
IncludeContainer includes;
bool include_modified( struct IncludeFile inc );
private:
bool is_handling_dependencies;
std::string path;