]> git.tdb.fi Git - builder.git/commitdiff
Add DependencyCache to speed up build preparation
authorMikko Rasa <tdb@tdb.fi>
Thu, 23 Aug 2007 17:18:24 +0000 (17:18 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 23 Aug 2007 17:18:24 +0000 (17:18 +0000)
source/builder.cpp
source/dependencycache.cpp [new file with mode: 0644]
source/dependencycache.h [new file with mode: 0644]
source/package.cpp
source/package.h
source/sourcefile.cpp

index 98e2a0721c0895308f19c828d9a01eb22c9c3c3f..353bc29a74588945142b29b536bfa17e201ec1e7 100644 (file)
@@ -583,6 +583,9 @@ int Builder::create_targets()
                world->prepare();
        }
 
+       for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i)
+               i->second->get_deps_cache().save();
+
        return 0;
 }
 
diff --git a/source/dependencycache.cpp b/source/dependencycache.cpp
new file mode 100644 (file)
index 0000000..cc11383
--- /dev/null
@@ -0,0 +1,79 @@
+/* $Id$
+
+This file is part of builder
+Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <fstream>
+#include <msp/path/utils.h>
+#include <msp/strings/utils.h>
+#include "builder.h"
+#include "dependencycache.h"
+#include "package.h"
+
+using namespace std;
+using namespace Msp;
+
+DependencyCache::DependencyCache(Package &p):
+       package(p),
+       changed(false)
+{ }
+
+const StringList &DependencyCache::get_deps(const string &tgt) const
+{
+       DepsMap::const_iterator i=deps.find(tgt);
+       if(i==deps.end())
+       {
+               static StringList dummy;
+               return dummy;
+       }
+       return i->second;
+}
+
+void DependencyCache::set_deps(const string &tgt, const StringList &d)
+{
+       deps[tgt]=d;
+       changed=true;
+}
+
+/**
+Saves the depencency cache.  If there are no cached dependencies or they
+haven't been changed, does nothing.
+*/
+void DependencyCache::save() const
+{
+       if(deps.empty() || !changed || package.get_builder().get_dry_run())
+               return;
+
+       ofstream out((package.get_source()/".deps").str().c_str());
+       if(!out)
+               return;
+
+       for(DepsMap::const_iterator i=deps.begin(); i!=deps.end(); ++i)
+       {
+               out<<i->first;
+               for(StringList::const_iterator j=i->second.begin(); j!=i->second.end(); ++j)
+                       out<<'|'<<*j;
+               out<<'\n';
+       }
+}
+
+void DependencyCache::load()
+{
+       string fn=(package.get_source()/".deps").str();
+       ifstream in(fn.c_str());
+       if(!in)
+               return;
+
+       string line;
+       while(getline(in, line))
+       {
+               vector<string> parts=split(line, '|');
+               deps[parts[0]]=StringList(parts.begin()+1, parts.end());
+       }
+
+       struct stat st;
+       Path::stat(fn, st);
+       mtime=Time::TimeStamp::from_unixtime(st.st_mtime);
+}
diff --git a/source/dependencycache.h b/source/dependencycache.h
new file mode 100644 (file)
index 0000000..5cde40d
--- /dev/null
@@ -0,0 +1,39 @@
+/* $Id$
+
+This file is part of builder
+Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef DEPENDENCYCACHE_H_
+#define DEPENDENCYCACHE_H_
+
+#include <msp/time/timestamp.h>
+#include "misc.h"
+
+class Package;
+
+/**
+Stores dependencies to avoid expensive operations during DAG building phase.
+The dependencies are stored in a map with target name as key and a list of
+strings as value.  The targets are free to store whatever they want here.
+*/
+class DependencyCache
+{
+public:
+       DependencyCache(Package &p);
+       void             set_deps(const std::string &tgt, const StringList &d);
+       const StringList &get_deps(const std::string &tgt) const;
+       const Msp::Time::TimeStamp &get_mtime() const { return mtime; }
+       void             load();
+       void             save() const;
+private:
+       typedef std::map<std::string, StringList> DepsMap;
+
+       Package &package;
+       DepsMap deps;
+       Msp::Time::TimeStamp mtime;
+       bool changed;
+};
+
+#endif
index 372cf2807be01997fed3733c81cc81d558516a03..8fb2b4dde4ffe8dda0e0b2507aca1174ca7ee968 100644 (file)
@@ -26,6 +26,7 @@ Package::Package(Builder &b, const string &n, const Path::Path &s):
        source(s),
        config(*this),
        conf_done(false),
+       deps_cache(*this),
        use_pkgconfig(true),
        need_path(false)
 {
@@ -167,6 +168,8 @@ void Package::configure(const StringMap &opts, unsigned flag)
                                (*i)->set_path(config.get_option((*i)->get_name()+"_path").value);
                        (*i)->configure(opts, flag&2);
                }
+
+               deps_cache.load();
        }
 
        create_build_info();
@@ -225,7 +228,8 @@ Package::Package(Builder &b, const string &n, const vector<string> &info):
        name(n),
        buildable(false),
        config(*this),
-       conf_done(false)
+       conf_done(false),
+       deps_cache(*this)
 {
        for(vector<string>::const_iterator i=info.begin(); i!=info.end(); ++i)
        {
@@ -358,6 +362,7 @@ void Package::create_build_info()
        export_binfo.unique();
 }
 
+
 Package::Loader::Loader(Package &p):
        pkg(p)
 {
index 68af269a9c6b4d0575e0dedfba9ca9b5c0c2e924..90ee6bc510abc941262d884146c6d053db32f522 100644 (file)
@@ -15,6 +15,7 @@ Distributed under the LGPL
 #include "component.h"
 #include "condition.h"
 #include "config.h"
+#include "dependencycache.h"
 #include "feature.h"
 #include "packageref.h"
 
@@ -81,6 +82,7 @@ public:
        const std::string   &get_arch() const           { return config.get_option("arch").value; }
        LibMode             get_library_mode() const;
        const PathList      &get_tar_files() const      { return tar_files; }
+       DependencyCache     &get_deps_cache() const     { return deps_cache; }
        void                resolve_refs();
        void                configure(const StringMap &, unsigned);
 
@@ -103,6 +105,7 @@ private:
        ComponentList components;
        Config        config;
        bool          conf_done;
+       mutable DependencyCache deps_cache;
        PathList      tar_files;
 
        bool          use_pkgconfig;
index f24dd0786ea5f314ead5821735d122b98fa120e3..57866aa274565c3b088f285abb1b2c234223f8bf 100644 (file)
@@ -26,15 +26,23 @@ from Builder.
 */
 void SourceFile::find_depends()
 {
-       ifstream in(name.c_str());
-       if(!in) return;
+       DependencyCache &deps_cache=comp->get_package().get_deps_cache();
+       if(mtime>deps_cache.get_mtime())
+       {
+               ifstream in(name.c_str());
+               if(!in) return;
+
+               Regex r_include("^[ \t]*#include[ \t]+([\"<].*)[\">]");
 
-       Regex r_include("^[ \t]*#include[ \t]+([\"<].*)[\">]");
+               string line;
+               while(getline(in, line))
+                       if(RegMatch match=r_include.match(line))
+                               includes.push_back(match[1].str);
 
-       string line;
-       while(getline(in, line))
-               if(RegMatch match=r_include.match(line))
-                       includes.push_back(match[1].str);
+               deps_cache.set_deps(name, includes);
+       }
+       else
+               includes=deps_cache.get_deps(name);
 
        const StringList &incpath=comp->get_build_info().incpath;
        const string &arch=comp->get_package().get_arch();