* When computing the set of paths referenced by an expression, also

include the paths of the subterms.
This commit is contained in:
Eelco Dolstra 2003-07-09 15:02:03 +00:00
parent 9a99dc736d
commit 2b95a9dc05
4 changed files with 68 additions and 44 deletions

View file

@ -180,7 +180,7 @@ static Expr evalExpr(Expr e)
SYSTEM, builder.c_str(), ins, out.c_str(), env); SYSTEM, builder.c_str(), ins, out.c_str(), env);
/* Write the resulting term into the Nix store directory. */ /* Write the resulting term into the Nix store directory. */
Hash eHash = writeTerm(e); Hash eHash = writeTerm(e, "-d-" + name);
return ATmake("Include(<str>)", ((string) eHash).c_str()); return ATmake("Include(<str>)", ((string) eHash).c_str());
} }

View file

@ -1,5 +1,4 @@
#include <map> #include <map>
#include <set>
#include <iostream> #include <iostream>
#include <sys/types.h> #include <sys/types.h>
@ -148,30 +147,50 @@ Hash hashTerm(ATerm t)
} }
ATerm termFromHash(const Hash & hash) ATerm termFromHash(const Hash & hash, string * p)
{ {
string path = queryPathByHash(hash); string path = queryPathByHash(hash);
if (p) *p = path;
ATerm t = ATreadFromNamedFile(path.c_str()); ATerm t = ATreadFromNamedFile(path.c_str());
if (!t) throw Error(format("cannot read aterm %1%") % path); if (!t) throw Error(format("cannot read aterm %1%") % path);
return t; return t;
} }
Hash writeTerm(ATerm t) Hash writeTerm(ATerm t, const string & suffix, string * p)
{ {
string path = nixStore + "/tmp.nix"; /* !!! */ string path = nixStore + "/tmp.nix"; /* !!! */
if (!ATwriteToNamedTextFile(t, path.c_str())) if (!ATwriteToNamedTextFile(t, path.c_str()))
throw Error(format("cannot write aterm %1%") % path); throw Error(format("cannot write aterm %1%") % path);
Hash hash = hashPath(path); Hash hash = hashPath(path);
string path2 = canonPath(nixStore + "/" + (string) hash + ".nix"); string path2 = canonPath(nixStore + "/" +
(string) hash + suffix + ".nix");
if (rename(path.c_str(), path2.c_str()) == -1) if (rename(path.c_str(), path2.c_str()) == -1)
throw SysError(format("renaming %1% to %2%") % path % path2); throw SysError(format("renaming %1% to %2%") % path % path2);
registerPath(path2, hash); registerPath(path2, hash);
if (p) *p = path2;
return hash; return hash;
} }
static FState realise(FState fs) FState storeSuccessor(FState fs, FState sc, StringSet & paths)
{
if (fs == sc) return sc;
string path;
Hash fsHash = hashTerm(fs);
Hash scHash = writeTerm(sc, "-s-" + (string) fsHash, &path);
setDB(nixDB, dbSuccessors, fsHash, scHash);
paths.insert(path);
#if 0
return ATmake("Include(<str>)", ((string) scHash).c_str());
#endif
return sc;
}
static FState realise(FState fs, StringSet & paths)
{ {
char * s1, * s2, * s3; char * s1, * s2, * s3;
Content content; Content content;
@ -183,7 +202,9 @@ static FState realise(FState fs)
string fsHash, scHash; string fsHash, scHash;
while (queryDB(nixDB, dbSuccessors, fsHash = hashTerm(fs), scHash)) { while (queryDB(nixDB, dbSuccessors, fsHash = hashTerm(fs), scHash)) {
debug(format("successor %1% -> %2%") % (string) fsHash % scHash); debug(format("successor %1% -> %2%") % (string) fsHash % scHash);
FState fs2 = termFromHash(parseHash(scHash)); string path;
FState fs2 = termFromHash(parseHash(scHash), &path);
paths.insert(path);
if (fs == fs2) { if (fs == fs2) {
debug(format("successor cycle detected in %1%") % printTerm(fs)); debug(format("successor cycle detected in %1%") % printTerm(fs));
break; break;
@ -195,7 +216,10 @@ static FState realise(FState fs)
/* Fall through. */ /* Fall through. */
if (ATmatch(fs, "Include(<str>)", &s1)) { if (ATmatch(fs, "Include(<str>)", &s1)) {
return realise(termFromHash(parseHash(s1))); string path;
fs = termFromHash(parseHash(s1), &path);
paths.insert(path);
return realise(fs, paths);
} }
else if (ATmatch(fs, "Path(<str>, <term>, [<list>])", &s1, &content, &refs)) { else if (ATmatch(fs, "Path(<str>, <term>, [<list>])", &s1, &content, &refs)) {
@ -210,7 +234,7 @@ static FState realise(FState fs)
/* Realise referenced paths. */ /* Realise referenced paths. */
ATermList refs2 = ATempty; ATermList refs2 = ATempty;
while (!ATisEmpty(refs)) { while (!ATisEmpty(refs)) {
refs2 = ATinsert(refs2, realise(ATgetFirst(refs))); refs2 = ATinsert(refs2, realise(ATgetFirst(refs), paths));
refs = ATgetNext(refs); refs = ATgetNext(refs);
} }
refs2 = ATreverse(refs2); refs2 = ATreverse(refs2);
@ -224,27 +248,26 @@ static FState realise(FState fs)
path.c_str(), content, refs2); path.c_str(), content, refs2);
/* Register the normal form. */ /* Register the normal form. */
if (fs != nf) { nf = storeSuccessor(fs, nf, paths);
Hash nfHash = writeTerm(nf);
setDB(nixDB, dbSuccessors, hashTerm(fs), nfHash);
}
/* Perhaps the path already exists and has the right hash? */ /* Perhaps the path already exists and has the right hash? */
if (pathExists(path)) { if (pathExists(path)) {
if (hash == hashPath(path)) {
debug(format("path %1% already has hash %2%") if (hash != hashPath(path))
throw Error(format("path %1% exists, but does not have hash %2%")
% path % (string) hash); % path % (string) hash);
return nf;
}
throw Error(format("path %1% exists, but does not have hash %2%") debug(format("path %1% already has hash %2%")
% path % (string) hash); % path % (string) hash);
} else {
/* Do we know a path with that hash? If so, copy it. */
string path2 = queryPathByHash(hash);
copyPath(path2, path);
} }
/* Do we know a path with that hash? If so, copy it. */
string path2 = queryPathByHash(hash);
copyPath(path2, path);
return nf; return nf;
} }
@ -261,7 +284,7 @@ static FState realise(FState fs)
/* Realise inputs. */ /* Realise inputs. */
ATermList ins2 = ATempty; ATermList ins2 = ATempty;
while (!ATisEmpty(ins)) { while (!ATisEmpty(ins)) {
ins2 = ATinsert(ins2, realise(ATgetFirst(ins))); ins2 = ATinsert(ins2, realise(ATgetFirst(ins), paths));
ins = ATgetNext(ins); ins = ATgetNext(ins);
} }
ins2 = ATreverse(ins2); ins2 = ATreverse(ins2);
@ -306,8 +329,7 @@ static FState realise(FState fs)
/* Register the normal form of fs. */ /* Register the normal form of fs. */
FState nf = ATmake("Path(<str>, Hash(<str>), <term>)", FState nf = ATmake("Path(<str>, Hash(<str>), <term>)",
outPath.c_str(), ((string) outHash).c_str(), ins2); outPath.c_str(), ((string) outHash).c_str(), ins2);
Hash nfHash = writeTerm(nf); nf = storeSuccessor(fs, nf, paths);
setDB(nixDB, dbSuccessors, hashTerm(fs), nfHash);
return nf; return nf;
} }
@ -316,9 +338,9 @@ static FState realise(FState fs)
} }
FState realiseFState(FState fs) FState realiseFState(FState fs, StringSet & paths)
{ {
return realise(fs); return realise(fs, paths);
} }
@ -338,9 +360,6 @@ string fstatePath(FState fs)
} }
typedef set<string> StringSet;
void fstateRefs2(FState fs, StringSet & paths) void fstateRefs2(FState fs, StringSet & paths)
{ {
char * s1, * s2, * s3; char * s1, * s2, * s3;
@ -372,11 +391,7 @@ void fstateRefs2(FState fs, StringSet & paths)
} }
Strings fstateRefs(FState fs) void fstateRefs(FState fs, StringSet & paths)
{ {
StringSet paths;
fstateRefs2(fs, paths); fstateRefs2(fs, paths);
Strings paths2(paths.size());
copy(paths.begin(), paths.end(), paths2.begin());
return paths2;
} }

View file

@ -1,6 +1,8 @@
#ifndef __EVAL_H #ifndef __EVAL_H
#define __EVAL_H #define __EVAL_H
#include <set>
extern "C" { extern "C" {
#include <aterm2.h> #include <aterm2.h>
} }
@ -59,17 +61,19 @@ using namespace std;
typedef ATerm FState; typedef ATerm FState;
typedef ATerm Content; typedef ATerm Content;
typedef set<string> StringSet;
/* Realise an fstate expression in the file system. This requires /* Realise an fstate expression in the file system. This requires
execution of all Derive() nodes. */ execution of all Derive() nodes. */
FState realiseFState(FState fs); FState realiseFState(FState fs, StringSet & paths);
/* Return the path of an fstate expression. An empty string is /* Return the path of an fstate expression. An empty string is
returned if the term is not a valid fstate expression. (!!!) */ returned if the term is not a valid fstate expression. (!!!) */
string fstatePath(FState fs); string fstatePath(FState fs);
/* Return the paths referenced by fstate expression. */ /* Return the paths referenced by fstate expression. */
Strings fstateRefs(FState fs); void fstateRefs(FState fs, StringSet & paths);
/* Return a canonical textual representation of an expression. */ /* Return a canonical textual representation of an expression. */
string printTerm(ATerm t); string printTerm(ATerm t);
@ -82,10 +86,10 @@ Error badTerm(const format & f, ATerm t);
Hash hashTerm(ATerm t); Hash hashTerm(ATerm t);
/* Read an aterm from disk, given its hash. */ /* Read an aterm from disk, given its hash. */
ATerm termFromHash(const Hash & hash); ATerm termFromHash(const Hash & hash, string * p = 0);
/* Write an aterm to the Nix store directory, and return its hash. */ /* Write an aterm to the Nix store directory, and return its hash. */
Hash writeTerm(ATerm t); Hash writeTerm(ATerm t, const string & suffix, string * p = 0);
#endif /* !__EVAL_H */ #endif /* !__EVAL_H */

View file

@ -96,7 +96,10 @@ static void opInstall(Strings opFlags, Strings opArgs)
for (Strings::iterator it = opArgs.begin(); for (Strings::iterator it = opArgs.begin();
it != opArgs.end(); it++) it != opArgs.end(); it++)
realiseFState(termFromHash(argToHash(*it))); {
StringSet paths;
realiseFState(termFromHash(argToHash(*it)), paths);
}
} }
@ -160,8 +163,10 @@ static void opQuery(Strings opFlags, Strings opArgs)
break; break;
case qRefs: { case qRefs: {
Strings refs = fstateRefs(realiseFState(termFromHash(hash))); StringSet refs;
for (Strings::iterator j = refs.begin(); FState fs = ATmake("Include(<str>)", ((string) hash).c_str());
fstateRefs(realiseFState(fs, refs), refs);
for (StringSet::iterator j = refs.begin();
j != refs.end(); j++) j != refs.end(); j++)
cout << format("%s\n") % *j; cout << format("%s\n") % *j;
break; break;