summaryrefslogtreecommitdiff
path: root/src/ModuleCache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ModuleCache.cc')
-rw-r--r--src/ModuleCache.cc66
1 files changed, 41 insertions, 25 deletions
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc
index 4944495..99c0b20 100644
--- a/src/ModuleCache.cc
+++ b/src/ModuleCache.cc
@@ -14,50 +14,58 @@
#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;
-static bool is_modified(const std::string &filename, const time_t &mtime)
-{
- struct stat st;
- memset(&st, 0, sizeof(struct stat));
- stat(filename.c_str(), &st);
- return (st.st_mtime > mtime);
-}
+/*!
+ Reevaluate the given file and recompile if necessary.
+ Returns NULL on any error (e.g. compile error or file not found)
+ If the given filename is relative, it means that the module hasn't been
+ previously located.
+*/
FileModule *ModuleCache::evaluate(const std::string &filename)
{
- FileModule *lib_mod = NULL;
+ FileModule *lib_mod = (this->entries.find(filename) != this->entries.end()) ?
+ &(*this->entries[filename].module) : NULL;
+
+ // Don't try to recursively evaluate - if the file changes
+ // during evaluation, that would be really bad.
+ if (lib_mod && lib_mod->isHandlingDependencies()) return lib_mod;
+
+ bool shouldCompile = true;
- // Create cache ID
+ // Create cache ID
struct stat st;
memset(&st, 0, sizeof(struct stat));
- stat(filename.c_str(), &st);
+ bool valid = (stat(filename.c_str(), &st) == 0);
+ // If file isn't there, just return and let the cache retain the old module
+ if (!valid) return NULL;
+
std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size);
- // Lookup in cache
- if (this->entries.find(filename) != this->entries.end() &&
- this->entries[filename].cache_id == cache_id) {
-#ifdef DEBUG
-// Causes too much debug output
-// PRINTB("Using cached library: %s (%s)", filename % cache_id);
-#endif
- lib_mod = &(*this->entries[filename].module);
+ // Lookup in cache
+ if (lib_mod) {
+ if (this->entries[filename].cache_id == cache_id) {
+ shouldCompile = false;
- BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, lib_mod->includes) {
- if (is_modified(item.first, item.second)) {
+ if (lib_mod->includesChanged()) {
lib_mod = NULL;
- break;
+ shouldCompile = true;
}
}
}
+ else {
+ shouldCompile = valid;
+ }
- // If cache lookup failed (non-existing or old timestamp), compile module
- if (!lib_mod) {
+ // If cache lookup failed (non-existing or old timestamp), compile module
+ if (shouldCompile) {
#ifdef DEBUG
if (this->entries.find(filename) != this->entries.end()) {
PRINTB("Recompiling cached library: %s (%s)", filename % cache_id);
@@ -91,7 +99,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 {
@@ -101,7 +109,9 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
print_messages_pop();
}
- if (lib_mod) lib_mod->handleDependencies();
+ if (lib_mod) {
+ lib_mod->handleDependencies();
+ }
return lib_mod;
}
@@ -111,3 +121,9 @@ void ModuleCache::clear()
this->entries.clear();
}
+FileModule *ModuleCache::lookup(const std::string &filename)
+{
+ return (this->entries.find(filename) != this->entries.end()) ?
+ &(*this->entries[filename].module) : NULL;
+}
+
contact: Jan Huwald // Impressum