summaryrefslogtreecommitdiff
path: root/src/ModuleCache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ModuleCache.cc')
-rw-r--r--src/ModuleCache.cc98
1 files changed, 55 insertions, 43 deletions
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc
index 1b7a9e5..d79a026 100644
--- a/src/ModuleCache.cc
+++ b/src/ModuleCache.cc
@@ -22,51 +22,68 @@
ModuleCache *ModuleCache::inst = NULL;
/*!
- Reevaluate the given file and recompile if necessary.
- Returns NULL on any error (e.g. compile error or file not found)
+ Reevaluate the given file and all it's dependencies and recompile anything
+ needing reevaluation.
+ The given filename must be absolute.
- If the given filename is relative, it means that the module hasn't been
- previously located.
+ Sets the module reference to the new modile, or NULL on any error (e.g. compile
+ error or file not found)
+
+ Returns true if anything was compiled (module or dependencies) and false otherwise.
*/
-FileModule *ModuleCache::evaluate(const std::string &filename)
+bool ModuleCache::evaluate(const std::string &filename, FileModule *&module)
{
- FileModule *lib_mod = (this->entries.find(filename) != this->entries.end()) ?
- &(*this->entries[filename].module) : NULL;
-
+ FileModule *lib_mod = NULL;
+ bool found = false;
+ if (this->entries.find(filename) != this->entries.end()) {
+ found = true;
+ lib_mod = this->entries[filename].module;
+ }
+
// 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
struct stat st;
memset(&st, 0, sizeof(struct stat));
bool valid = (stat(filename.c_str(), &st) == 0);
- // If file isn't there, just return and let the cache retain the old module
+ // If file isn't there, just return and let the cache retain the old module
if (!valid) return NULL;
-
+
+ // If the file is present, we'll always cache some result
std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size);
- // Lookup in cache
- if (lib_mod) {
- if (this->entries[filename].cache_id == cache_id) {
+ cache_entry &entry = this->entries[filename];
+ // Initialize entry, if new
+ if (!found) {
+ entry.module = NULL;
+ entry.cache_id = cache_id;
+ }
+
+ bool shouldCompile = true;
+ if (found) {
+ // Files should only be recompiled if the cache ID changed
+ if (entry.cache_id == cache_id) {
shouldCompile = false;
- if (lib_mod->includesChanged()) {
+ // Recompile if includes changed
+ if (lib_mod && lib_mod->includesChanged()) {
lib_mod = NULL;
shouldCompile = true;
}
}
}
- else {
- shouldCompile = valid;
- }
+
+#ifdef DEBUG
+ // Causes too much debug output
+ //if (!shouldCompile) PRINTB("Using cached library: %s (%p)", filename % lib_mod);
+#endif
// If cache lookup failed (non-existing or old timestamp), compile module
if (shouldCompile) {
#ifdef DEBUG
- if (this->entries.find(filename) != this->entries.end()) {
+ if (found) {
PRINTB("Recompiling cached library: %s (%s)", filename % cache_id);
}
else {
@@ -84,37 +101,28 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
textbuf << ifs.rdbuf();
}
textbuf << "\n" << commandline_commands;
-
+
print_messages_push();
-
- FileModule *oldmodule = NULL;
- cache_entry e = { NULL, cache_id };
- if (this->entries.find(filename) != this->entries.end()) {
- oldmodule = this->entries[filename].module;
- }
- this->entries[filename] = e;
+
+ FileModule *oldmodule = lib_mod;
std::string pathname = boosty::stringy(fs::path(filename).parent_path());
lib_mod = dynamic_cast<FileModule*>(parse(textbuf.str().c_str(), pathname.c_str(), false));
PRINTB_NOCACHE(" compiled module: %p", lib_mod);
- if (lib_mod) {
- // We defer deletion so we can ensure that the new module won't
- // have the same address as the old
- delete oldmodule;
- this->entries[filename].module = lib_mod;
- } else {
- this->entries.erase(filename);
- }
+ // We defer deletion so we can ensure that the new module won't
+ // have the same address as the old
+ if (oldmodule) delete oldmodule;
+ entry.module = lib_mod;
+ entry.cache_id = cache_id;
print_messages_pop();
}
+
+ module = lib_mod;
+ bool depschanged = lib_mod ? lib_mod->handleDependencies() : false;
- if (lib_mod) {
- lib_mod->handleDependencies();
- }
-
- return lib_mod;
+ return shouldCompile || depschanged;
}
void ModuleCache::clear()
@@ -124,7 +132,11 @@ void ModuleCache::clear()
FileModule *ModuleCache::lookup(const std::string &filename)
{
- return (this->entries.find(filename) != this->entries.end()) ?
- &(*this->entries[filename].module) : NULL;
+ return isCached(filename) ? this->entries[filename].module : NULL;
+}
+
+bool ModuleCache::isCached(const std::string &filename)
+{
+ return this->entries.find(filename) != this->entries.end();
}
contact: Jan Huwald // Impressum