mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-26 07:46:21 +02:00
* Use maps and sets in the FState data type. This ensures normalisation of
slices and derivations w.r.t. order of paths, slice elements, etc.
This commit is contained in:
parent
624c48260f
commit
956801fcc2
5 changed files with 86 additions and 105 deletions
19
src/fix.cc
19
src/fix.cc
|
@ -137,14 +137,16 @@ static Strings fstatePathsCached(EvalState & state, const FSId & id)
|
||||||
static Hash hashPackage(EvalState & state, FState fs)
|
static Hash hashPackage(EvalState & state, FState fs)
|
||||||
{
|
{
|
||||||
if (fs.type == FState::fsDerive) {
|
if (fs.type == FState::fsDerive) {
|
||||||
for (FSIds::iterator i = fs.derive.inputs.begin();
|
FSIdSet inputs2;
|
||||||
|
for (FSIdSet::iterator i = fs.derive.inputs.begin();
|
||||||
i != fs.derive.inputs.end(); i++)
|
i != fs.derive.inputs.end(); i++)
|
||||||
{
|
{
|
||||||
PkgHashes::iterator j = state.pkgHashes.find(*i);
|
PkgHashes::iterator j = state.pkgHashes.find(*i);
|
||||||
if (j == state.pkgHashes.end())
|
if (j == state.pkgHashes.end())
|
||||||
throw Error(format("unknown package id %1%") % (string) *i);
|
throw Error(format("unknown package id %1%") % (string) *i);
|
||||||
*i = j->second;
|
inputs2.insert(j->second);
|
||||||
}
|
}
|
||||||
|
fs.derive.inputs = inputs2;
|
||||||
}
|
}
|
||||||
return hashTerm(unparseFState(fs));
|
return hashTerm(unparseFState(fs));
|
||||||
}
|
}
|
||||||
|
@ -159,7 +161,7 @@ static string processBinding(EvalState & state, Expr e, FState & fs)
|
||||||
Strings paths = fstatePathsCached(state, id);
|
Strings paths = fstatePathsCached(state, id);
|
||||||
if (paths.size() != 1) abort();
|
if (paths.size() != 1) abort();
|
||||||
string path = *(paths.begin());
|
string path = *(paths.begin());
|
||||||
fs.derive.inputs.push_back(id);
|
fs.derive.inputs.insert(id);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,12 +266,11 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
||||||
addToStore(srcPath, dstPath, id, true);
|
addToStore(srcPath, dstPath, id, true);
|
||||||
|
|
||||||
SliceElem elem;
|
SliceElem elem;
|
||||||
elem.path = dstPath;
|
|
||||||
elem.id = id;
|
elem.id = id;
|
||||||
FState fs;
|
FState fs;
|
||||||
fs.type = FState::fsSlice;
|
fs.type = FState::fsSlice;
|
||||||
fs.slice.roots.push_back(dstPath);
|
fs.slice.roots.insert(dstPath);
|
||||||
fs.slice.elems.push_back(elem);
|
fs.slice.elems[dstPath] = elem;
|
||||||
|
|
||||||
Hash pkgHash = hashPackage(state, fs);
|
Hash pkgHash = hashPackage(state, fs);
|
||||||
FSId pkgId = writeTerm(unparseFState(fs), "");
|
FSId pkgId = writeTerm(unparseFState(fs), "");
|
||||||
|
@ -324,7 +325,7 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
||||||
|
|
||||||
else {
|
else {
|
||||||
string s = processBinding(state, value, fs);
|
string s = processBinding(state, value, fs);
|
||||||
fs.derive.env.push_back(StringPair(key, s));
|
fs.derive.env[key] = s;
|
||||||
|
|
||||||
if (key == "build") fs.derive.builder = s;
|
if (key == "build") fs.derive.builder = s;
|
||||||
if (key == "name") name = s;
|
if (key == "name") name = s;
|
||||||
|
@ -349,8 +350,8 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
||||||
if (!outIdGiven) outId = hashPackage(state, fs);
|
if (!outIdGiven) outId = hashPackage(state, fs);
|
||||||
string outPath =
|
string outPath =
|
||||||
canonPath(nixStore + "/" + ((string) outId).c_str() + "-" + name);
|
canonPath(nixStore + "/" + ((string) outId).c_str() + "-" + name);
|
||||||
fs.derive.env.push_back(StringPair("out", outPath));
|
fs.derive.env["out"] = outPath;
|
||||||
fs.derive.outputs.push_back(DeriveOutput(outPath, outId));
|
fs.derive.outputs[outPath] = outId;
|
||||||
|
|
||||||
/* Write the resulting term into the Nix store directory. */
|
/* Write the resulting term into the Nix store directory. */
|
||||||
Hash pkgHash = outIdGiven
|
Hash pkgHash = outIdGiven
|
||||||
|
|
|
@ -52,14 +52,14 @@ FSId writeTerm(ATerm t, const string & suffix, FSId id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void parsePaths(ATermList paths, Strings & out)
|
static void parsePaths(ATermList paths, StringSet & out)
|
||||||
{
|
{
|
||||||
while (!ATisEmpty(paths)) {
|
while (!ATisEmpty(paths)) {
|
||||||
char * s;
|
char * s;
|
||||||
ATerm t = ATgetFirst(paths);
|
ATerm t = ATgetFirst(paths);
|
||||||
if (!ATmatch(t, "<str>", &s))
|
if (!ATmatch(t, "<str>", &s))
|
||||||
throw badTerm("not a path", t);
|
throw badTerm("not a path", t);
|
||||||
out.push_back(s);
|
out.insert(s);
|
||||||
paths = ATgetNext(paths);
|
paths = ATgetNext(paths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,21 +73,21 @@ static void checkSlice(const Slice & slice)
|
||||||
StringSet decl;
|
StringSet decl;
|
||||||
for (SliceElems::const_iterator i = slice.elems.begin();
|
for (SliceElems::const_iterator i = slice.elems.begin();
|
||||||
i != slice.elems.end(); i++)
|
i != slice.elems.end(); i++)
|
||||||
decl.insert(i->path);
|
decl.insert(i->first);
|
||||||
|
|
||||||
for (Strings::const_iterator i = slice.roots.begin();
|
for (StringSet::const_iterator i = slice.roots.begin();
|
||||||
i != slice.roots.end(); i++)
|
i != slice.roots.end(); i++)
|
||||||
if (decl.find(*i) == decl.end())
|
if (decl.find(*i) == decl.end())
|
||||||
throw Error(format("undefined root path `%1%'") % *i);
|
throw Error(format("undefined root path `%1%'") % *i);
|
||||||
|
|
||||||
for (SliceElems::const_iterator i = slice.elems.begin();
|
for (SliceElems::const_iterator i = slice.elems.begin();
|
||||||
i != slice.elems.end(); i++)
|
i != slice.elems.end(); i++)
|
||||||
for (Strings::const_iterator j = i->refs.begin();
|
for (StringSet::const_iterator j = i->second.refs.begin();
|
||||||
j != i->refs.end(); j++)
|
j != i->second.refs.end(); j++)
|
||||||
if (decl.find(*j) == decl.end())
|
if (decl.find(*j) == decl.end())
|
||||||
throw Error(
|
throw Error(
|
||||||
format("undefined path `%1%' referenced by `%2%'")
|
format("undefined path `%1%' referenced by `%2%'")
|
||||||
% *j % i->path);
|
% *j % i->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,10 +108,9 @@ static bool parseSlice(ATerm t, Slice & slice)
|
||||||
if (!ATmatch(t, "(<str>, <str>, [<list>])", &s1, &s2, &refs))
|
if (!ATmatch(t, "(<str>, <str>, [<list>])", &s1, &s2, &refs))
|
||||||
throw badTerm("not a slice element", t);
|
throw badTerm("not a slice element", t);
|
||||||
SliceElem elem;
|
SliceElem elem;
|
||||||
elem.path = s1;
|
|
||||||
elem.id = parseHash(s2);
|
elem.id = parseHash(s2);
|
||||||
parsePaths(refs, elem.refs);
|
parsePaths(refs, elem.refs);
|
||||||
slice.elems.push_back(elem);
|
slice.elems[s1] = elem;
|
||||||
elems = ATgetNext(elems);
|
elems = ATgetNext(elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +140,7 @@ static bool parseDerive(ATerm t, Derive & derive)
|
||||||
ATerm t = ATgetFirst(outs);
|
ATerm t = ATgetFirst(outs);
|
||||||
if (!ATmatch(t, "(<str>, <str>)", &s1, &s2))
|
if (!ATmatch(t, "(<str>, <str>)", &s1, &s2))
|
||||||
throw badTerm("not a derive output", t);
|
throw badTerm("not a derive output", t);
|
||||||
derive.outputs.push_back(DeriveOutput(s1, parseHash(s2)));
|
derive.outputs[s1] = parseHash(s2);
|
||||||
outs = ATgetNext(outs);
|
outs = ATgetNext(outs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +149,7 @@ static bool parseDerive(ATerm t, Derive & derive)
|
||||||
ATerm t = ATgetFirst(ins);
|
ATerm t = ATgetFirst(ins);
|
||||||
if (!ATmatch(t, "<str>", &s))
|
if (!ATmatch(t, "<str>", &s))
|
||||||
throw badTerm("not an id", t);
|
throw badTerm("not an id", t);
|
||||||
derive.inputs.push_back(parseHash(s));
|
derive.inputs.insert(parseHash(s));
|
||||||
ins = ATgetNext(ins);
|
ins = ATgetNext(ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +170,7 @@ static bool parseDerive(ATerm t, Derive & derive)
|
||||||
ATerm bnd = ATgetFirst(bnds);
|
ATerm bnd = ATgetFirst(bnds);
|
||||||
if (!ATmatch(bnd, "(<str>, <str>)", &s1, &s2))
|
if (!ATmatch(bnd, "(<str>, <str>)", &s1, &s2))
|
||||||
throw badTerm("tuple of strings expected", bnd);
|
throw badTerm("tuple of strings expected", bnd);
|
||||||
derive.env.push_back(StringPair(s1, s2));
|
derive.env[s1] = s2;
|
||||||
bnds = ATgetNext(bnds);
|
bnds = ATgetNext(bnds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,10 +190,10 @@ FState parseFState(ATerm t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ATermList unparsePaths(const Strings & paths)
|
static ATermList unparsePaths(const StringSet & paths)
|
||||||
{
|
{
|
||||||
ATermList l = ATempty;
|
ATermList l = ATempty;
|
||||||
for (Strings::const_iterator i = paths.begin();
|
for (StringSet::const_iterator i = paths.begin();
|
||||||
i != paths.end(); i++)
|
i != paths.end(); i++)
|
||||||
l = ATinsert(l, ATmake("<str>", i->c_str()));
|
l = ATinsert(l, ATmake("<str>", i->c_str()));
|
||||||
return ATreverse(l);
|
return ATreverse(l);
|
||||||
|
@ -210,9 +209,9 @@ static ATerm unparseSlice(const Slice & slice)
|
||||||
i != slice.elems.end(); i++)
|
i != slice.elems.end(); i++)
|
||||||
elems = ATinsert(elems,
|
elems = ATinsert(elems,
|
||||||
ATmake("(<str>, <str>, <term>)",
|
ATmake("(<str>, <str>, <term>)",
|
||||||
i->path.c_str(),
|
i->first.c_str(),
|
||||||
((string) i->id).c_str(),
|
((string) i->second.id).c_str(),
|
||||||
unparsePaths(i->refs)));
|
unparsePaths(i->second.refs)));
|
||||||
|
|
||||||
return ATmake("Slice(<term>, <term>)", roots, elems);
|
return ATmake("Slice(<term>, <term>)", roots, elems);
|
||||||
}
|
}
|
||||||
|
@ -228,7 +227,7 @@ static ATerm unparseDerive(const Derive & derive)
|
||||||
i->first.c_str(), ((string) i->second).c_str()));
|
i->first.c_str(), ((string) i->second).c_str()));
|
||||||
|
|
||||||
ATermList ins = ATempty;
|
ATermList ins = ATempty;
|
||||||
for (FSIds::const_iterator i = derive.inputs.begin();
|
for (FSIdSet::const_iterator i = derive.inputs.begin();
|
||||||
i != derive.inputs.end(); i++)
|
i != derive.inputs.end(); i++)
|
||||||
ins = ATinsert(ins, ATmake("<str>", ((string) *i).c_str()));
|
ins = ATinsert(ins, ATmake("<str>", ((string) *i).c_str()));
|
||||||
|
|
||||||
|
|
|
@ -14,28 +14,25 @@ typedef list<FSId> FSIds;
|
||||||
|
|
||||||
struct SliceElem
|
struct SliceElem
|
||||||
{
|
{
|
||||||
string path;
|
|
||||||
FSId id;
|
FSId id;
|
||||||
Strings refs;
|
StringSet refs;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef list<SliceElem> SliceElems;
|
typedef map<string, SliceElem> SliceElems;
|
||||||
|
|
||||||
struct Slice
|
struct Slice
|
||||||
{
|
{
|
||||||
Strings roots;
|
StringSet roots;
|
||||||
SliceElems elems;
|
SliceElems elems;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef pair<string, FSId> DeriveOutput;
|
typedef map<string, FSId> DeriveOutputs;
|
||||||
typedef pair<string, string> StringPair;
|
typedef map<string, string> StringPairs;
|
||||||
typedef list<DeriveOutput> DeriveOutputs;
|
|
||||||
typedef list<StringPair> StringPairs;
|
|
||||||
|
|
||||||
struct Derive
|
struct Derive
|
||||||
{
|
{
|
||||||
DeriveOutputs outputs;
|
DeriveOutputs outputs;
|
||||||
FSIds inputs;
|
FSIdSet inputs;
|
||||||
string platform;
|
string platform;
|
||||||
string builder;
|
string builder;
|
||||||
Strings args;
|
Strings args;
|
||||||
|
|
|
@ -193,7 +193,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
string label, shape;
|
string label, shape;
|
||||||
|
|
||||||
if (fs.type == FState::fsDerive) {
|
if (fs.type == FState::fsDerive) {
|
||||||
for (FSIds::iterator i = fs.derive.inputs.begin();
|
for (FSIdSet::iterator i = fs.derive.inputs.begin();
|
||||||
i != fs.derive.inputs.end(); i++)
|
i != fs.derive.inputs.end(); i++)
|
||||||
{
|
{
|
||||||
workList.push_back(*i);
|
workList.push_back(*i);
|
||||||
|
@ -209,7 +209,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (fs.type == FState::fsSlice) {
|
else if (fs.type == FState::fsSlice) {
|
||||||
label = baseNameOf((*fs.slice.elems.begin()).path);
|
label = baseNameOf((*fs.slice.elems.begin()).first);
|
||||||
shape = "ellipse";
|
shape = "ellipse";
|
||||||
if (isHash(string(label, 0, Hash::hashSize * 2)) &&
|
if (isHash(string(label, 0, Hash::hashSize * 2)) &&
|
||||||
label[Hash::hashSize * 2] == '-')
|
label[Hash::hashSize * 2] == '-')
|
||||||
|
|
118
src/normalise.cc
118
src/normalise.cc
|
@ -26,14 +26,10 @@ static FSId useSuccessor(const FSId & id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef map<string, FSId> OutPaths;
|
Strings pathsFromOutputs(const DeriveOutputs & ps)
|
||||||
typedef map<string, SliceElem> ElemMap;
|
|
||||||
|
|
||||||
|
|
||||||
Strings pathsFromOutPaths(const OutPaths & ps)
|
|
||||||
{
|
{
|
||||||
Strings ss;
|
Strings ss;
|
||||||
for (OutPaths::const_iterator i = ps.begin();
|
for (DeriveOutputs::const_iterator i = ps.begin();
|
||||||
i != ps.end(); i++)
|
i != ps.end(); i++)
|
||||||
ss.push_back(i->first);
|
ss.push_back(i->first);
|
||||||
return ss;
|
return ss;
|
||||||
|
@ -62,31 +58,31 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
|
|
||||||
/* Some variables. */
|
/* Some variables. */
|
||||||
|
|
||||||
/* Output paths, with their ids. */
|
|
||||||
OutPaths outPaths;
|
|
||||||
|
|
||||||
/* Input paths, with their slice elements. */
|
/* Input paths, with their slice elements. */
|
||||||
ElemMap inMap;
|
SliceElems inSlices;
|
||||||
|
|
||||||
/* Referencable paths (i.e., input and output paths). */
|
/* Referencable paths (i.e., input and output paths). */
|
||||||
Strings allPaths;
|
StringSet allPaths;
|
||||||
|
|
||||||
/* The environment to be passed to the builder. */
|
/* The environment to be passed to the builder. */
|
||||||
Environment env;
|
Environment env;
|
||||||
|
|
||||||
|
/* The result. */
|
||||||
|
FState nfFS;
|
||||||
|
nfFS.type = FState::fsSlice;
|
||||||
|
|
||||||
|
|
||||||
/* Parse the outputs. */
|
/* Parse the outputs. */
|
||||||
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||||
i != fs.derive.outputs.end(); i++)
|
i != fs.derive.outputs.end(); i++)
|
||||||
{
|
{
|
||||||
debug(format("building %1% in `%2%'") % (string) i->second % i->first);
|
debug(format("building %1% in `%2%'") % (string) i->second % i->first);
|
||||||
outPaths[i->first] = i->second;
|
allPaths.insert(i->first);
|
||||||
allPaths.push_back(i->first);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Obtain locks on all output paths. The locks are automatically
|
/* Obtain locks on all output paths. The locks are automatically
|
||||||
released when we exit this function or Nix crashes. */
|
released when we exit this function or Nix crashes. */
|
||||||
PathLocks outputLocks(pathsFromOutPaths(outPaths));
|
PathLocks outputLocks(pathsFromOutputs(fs.derive.outputs));
|
||||||
|
|
||||||
/* Now check again whether there is a successor. This is because
|
/* Now check again whether there is a successor. This is because
|
||||||
another process may have started building in parallel. After
|
another process may have started building in parallel. After
|
||||||
|
@ -113,8 +109,9 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
% fs.derive.platform % thisSystem);
|
% fs.derive.platform % thisSystem);
|
||||||
|
|
||||||
/* Realise inputs (and remember all input paths). */
|
/* Realise inputs (and remember all input paths). */
|
||||||
for (FSIds::iterator i = fs.derive.inputs.begin();
|
for (FSIdSet::iterator i = fs.derive.inputs.begin();
|
||||||
i != fs.derive.inputs.end(); i++) {
|
i != fs.derive.inputs.end(); i++)
|
||||||
|
{
|
||||||
FSId nf = normaliseFState(*i, pending);
|
FSId nf = normaliseFState(*i, pending);
|
||||||
realiseSlice(nf, pending);
|
realiseSlice(nf, pending);
|
||||||
/* !!! nf should be a root of the garbage collector while we
|
/* !!! nf should be a root of the garbage collector while we
|
||||||
|
@ -123,12 +120,12 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
if (fs.type != FState::fsSlice) abort();
|
if (fs.type != FState::fsSlice) abort();
|
||||||
for (SliceElems::iterator j = fs.slice.elems.begin();
|
for (SliceElems::iterator j = fs.slice.elems.begin();
|
||||||
j != fs.slice.elems.end(); j++)
|
j != fs.slice.elems.end(); j++)
|
||||||
inMap[j->path] = *j;
|
{
|
||||||
|
inSlices[j->first] = j->second;
|
||||||
|
allPaths.insert(j->first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ElemMap::iterator i = inMap.begin(); i != inMap.end(); i++)
|
|
||||||
allPaths.push_back(i->second.path);
|
|
||||||
|
|
||||||
/* Most shells initialise PATH to some default (/bin:/usr/bin:...) when
|
/* Most shells initialise PATH to some default (/bin:/usr/bin:...) when
|
||||||
PATH is not set. We don't want this, so we fill it in with some dummy
|
PATH is not set. We don't want this, so we fill it in with some dummy
|
||||||
value. */
|
value. */
|
||||||
|
@ -142,8 +139,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
/* We can skip running the builder if we can expand all output
|
/* We can skip running the builder if we can expand all output
|
||||||
paths from their ids. */
|
paths from their ids. */
|
||||||
bool fastBuild = true;
|
bool fastBuild = true;
|
||||||
for (OutPaths::iterator i = outPaths.begin();
|
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||||
i != outPaths.end(); i++)
|
i != fs.derive.outputs.end(); i++)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
expandId(i->second, i->first, "/", pending);
|
expandId(i->second, i->first, "/", pending);
|
||||||
|
@ -159,8 +156,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
|
|
||||||
/* If any of the outputs already exist but are not registered,
|
/* If any of the outputs already exist but are not registered,
|
||||||
delete them. */
|
delete them. */
|
||||||
for (OutPaths::iterator i = outPaths.begin();
|
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||||
i != outPaths.end(); i++)
|
i != fs.derive.outputs.end(); i++)
|
||||||
{
|
{
|
||||||
string path = i->first;
|
string path = i->first;
|
||||||
FSId id;
|
FSId id;
|
||||||
|
@ -183,21 +180,21 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
/* Check whether the output paths were created, and grep each
|
/* Check whether the output paths were created, and grep each
|
||||||
output path to determine what other paths it references. */
|
output path to determine what other paths it references. */
|
||||||
StringSet usedPaths;
|
StringSet usedPaths;
|
||||||
for (OutPaths::iterator i = outPaths.begin();
|
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||||
i != outPaths.end(); i++)
|
i != fs.derive.outputs.end(); i++)
|
||||||
{
|
{
|
||||||
string path = i->first;
|
string path = i->first;
|
||||||
if (!pathExists(path))
|
if (!pathExists(path))
|
||||||
throw Error(format("path `%1%' does not exist") % path);
|
throw Error(format("path `%1%' does not exist") % path);
|
||||||
fs.slice.roots.push_back(path);
|
nfFS.slice.roots.insert(path);
|
||||||
|
|
||||||
/* For this output path, find the references to other paths contained
|
/* For this output path, find the references to other paths contained
|
||||||
in it. */
|
in it. */
|
||||||
Strings refPaths = filterReferences(path, allPaths);
|
Strings refPaths = filterReferences(path,
|
||||||
|
Strings(allPaths.begin(), allPaths.end()));
|
||||||
|
|
||||||
/* Construct a slice element for this output path. */
|
/* Construct a slice element for this output path. */
|
||||||
SliceElem elem;
|
SliceElem elem;
|
||||||
elem.path = path;
|
|
||||||
elem.id = i->second;
|
elem.id = i->second;
|
||||||
|
|
||||||
/* For each path referenced by this output path, add its id to the
|
/* For each path referenced by this output path, add its id to the
|
||||||
|
@ -207,18 +204,14 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
j != refPaths.end(); j++)
|
j != refPaths.end(); j++)
|
||||||
{
|
{
|
||||||
string path = *j;
|
string path = *j;
|
||||||
ElemMap::iterator k;
|
elem.refs.insert(path);
|
||||||
OutPaths::iterator l;
|
if (inSlices.find(path) != inSlices.end())
|
||||||
|
usedPaths.insert(path);
|
||||||
elem.refs.push_back(path);
|
else if (fs.derive.outputs.find(path) == fs.derive.outputs.end())
|
||||||
|
|
||||||
if ((k = inMap.find(path)) != inMap.end())
|
|
||||||
usedPaths.insert(k->second.path);
|
|
||||||
else if ((l = outPaths.find(path)) == outPaths.end())
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.slice.elems.push_back(elem);
|
nfFS.slice.elems[path] = elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close the slice. That is, for any referenced path, add the paths
|
/* Close the slice. That is, for any referenced path, add the paths
|
||||||
|
@ -233,31 +226,30 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
if (donePaths.find(path) != donePaths.end()) continue;
|
if (donePaths.find(path) != donePaths.end()) continue;
|
||||||
donePaths.insert(path);
|
donePaths.insert(path);
|
||||||
|
|
||||||
ElemMap::iterator j = inMap.find(path);
|
SliceElems::iterator j = inSlices.find(path);
|
||||||
if (j == inMap.end()) abort();
|
if (j == inSlices.end()) abort();
|
||||||
|
|
||||||
fs.slice.elems.push_back(j->second);
|
nfFS.slice.elems[path] = j->second;
|
||||||
|
|
||||||
for (Strings::iterator k = j->second.refs.begin();
|
for (StringSet::iterator k = j->second.refs.begin();
|
||||||
k != j->second.refs.end(); k++)
|
k != j->second.refs.end(); k++)
|
||||||
usedPaths.insert(*k);
|
usedPaths.insert(*k);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For debugging, print out the referenced and unreferenced paths. */
|
/* For debugging, print out the referenced and unreferenced paths. */
|
||||||
for (ElemMap::iterator i = inMap.begin();
|
for (SliceElems::iterator i = inSlices.begin();
|
||||||
i != inMap.end(); i++)
|
i != inSlices.end(); i++)
|
||||||
{
|
{
|
||||||
StringSet::iterator j = donePaths.find(i->second.path);
|
StringSet::iterator j = donePaths.find(i->first);
|
||||||
if (j == donePaths.end())
|
if (j == donePaths.end())
|
||||||
debug(format("NOT referenced: `%1%'") % i->second.path);
|
debug(format("NOT referenced: `%1%'") % i->first);
|
||||||
else
|
else
|
||||||
debug(format("referenced: `%1%'") % i->second.path);
|
debug(format("referenced: `%1%'") % i->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the normal form. This does not have to occur in the
|
/* Write the normal form. This does not have to occur in the
|
||||||
transaction below because writing terms is idem-potent. */
|
transaction below because writing terms is idem-potent. */
|
||||||
fs.type = FState::fsSlice;
|
ATerm nf = unparseFState(nfFS);
|
||||||
ATerm nf = unparseFState(fs);
|
|
||||||
msg(lvlVomit, format("normal form: %1%") % printTerm(nf));
|
msg(lvlVomit, format("normal form: %1%") % printTerm(nf));
|
||||||
FSId idNF = writeTerm(nf, "-s-" + (string) id);
|
FSId idNF = writeTerm(nf, "-s-" + (string) id);
|
||||||
|
|
||||||
|
@ -268,8 +260,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
||||||
deleted arbitrarily, while registered paths can only be deleted
|
deleted arbitrarily, while registered paths can only be deleted
|
||||||
by running the garbage collector. */
|
by running the garbage collector. */
|
||||||
Transaction txn(nixDB);
|
Transaction txn(nixDB);
|
||||||
for (OutPaths::iterator i = outPaths.begin();
|
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||||
i != outPaths.end(); i++)
|
i != fs.derive.outputs.end(); i++)
|
||||||
registerPath(txn, i->first, i->second);
|
registerPath(txn, i->first, i->second);
|
||||||
registerSuccessor(txn, id, idNF);
|
registerSuccessor(txn, id, idNF);
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
@ -289,10 +281,7 @@ void realiseSlice(const FSId & id, FSIdSet pending)
|
||||||
|
|
||||||
for (SliceElems::const_iterator i = fs.slice.elems.begin();
|
for (SliceElems::const_iterator i = fs.slice.elems.begin();
|
||||||
i != fs.slice.elems.end(); i++)
|
i != fs.slice.elems.end(); i++)
|
||||||
{
|
expandId(i->second.id, i->first, "/", pending);
|
||||||
SliceElem elem = *i;
|
|
||||||
expandId(elem.id, elem.path, "/", pending);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,12 +292,9 @@ Strings fstatePaths(const FSId & id)
|
||||||
FState fs = parseFState(termFromId(id));
|
FState fs = parseFState(termFromId(id));
|
||||||
|
|
||||||
if (fs.type == FState::fsSlice) {
|
if (fs.type == FState::fsSlice) {
|
||||||
/* !!! fix complexity */
|
for (StringSet::const_iterator i = fs.slice.roots.begin();
|
||||||
for (Strings::const_iterator i = fs.slice.roots.begin();
|
|
||||||
i != fs.slice.roots.end(); i++)
|
i != fs.slice.roots.end(); i++)
|
||||||
for (SliceElems::const_iterator j = fs.slice.elems.begin();
|
paths.push_back(*i);
|
||||||
j != fs.slice.elems.end(); j++)
|
|
||||||
if (*i == j->path) paths.push_back(j->path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (fs.type == FState::fsDerive) {
|
else if (fs.type == FState::fsDerive) {
|
||||||
|
@ -328,18 +314,16 @@ static void fstateRequisitesSet(const FSId & id,
|
||||||
{
|
{
|
||||||
FState fs = parseFState(termFromId(id));
|
FState fs = parseFState(termFromId(id));
|
||||||
|
|
||||||
if (fs.type == FState::fsSlice) {
|
if (fs.type == FState::fsSlice)
|
||||||
for (SliceElems::iterator i = fs.slice.elems.begin();
|
for (SliceElems::iterator i = fs.slice.elems.begin();
|
||||||
i != fs.slice.elems.end(); i++)
|
i != fs.slice.elems.end(); i++)
|
||||||
paths.insert(i->path);
|
paths.insert(i->first);
|
||||||
}
|
|
||||||
|
|
||||||
else if (fs.type == FState::fsDerive) {
|
else if (fs.type == FState::fsDerive)
|
||||||
for (FSIds::iterator i = fs.derive.inputs.begin();
|
for (FSIdSet::iterator i = fs.derive.inputs.begin();
|
||||||
i != fs.derive.inputs.end(); i++)
|
i != fs.derive.inputs.end(); i++)
|
||||||
fstateRequisitesSet(*i,
|
fstateRequisitesSet(*i,
|
||||||
includeExprs, includeSuccessors, paths);
|
includeExprs, includeSuccessors, paths);
|
||||||
}
|
|
||||||
|
|
||||||
else abort();
|
else abort();
|
||||||
|
|
||||||
|
@ -394,7 +378,7 @@ FSIds findGenerators(const FSIds & _ids)
|
||||||
bool okay = true;
|
bool okay = true;
|
||||||
for (SliceElems::const_iterator i = fs.slice.elems.begin();
|
for (SliceElems::const_iterator i = fs.slice.elems.begin();
|
||||||
i != fs.slice.elems.end(); i++)
|
i != fs.slice.elems.end(); i++)
|
||||||
if (ids.find(i->id) == ids.end()) {
|
if (ids.find(i->second.id) == ids.end()) {
|
||||||
okay = false;
|
okay = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue