* Update referers mappings when updating/clearing the references

mapping.
* Do things in the right order in invalidatePath().
This commit is contained in:
Eelco Dolstra 2005-01-27 16:18:39 +00:00
parent 4e37548a1e
commit c60a4943ba

View File

@ -253,6 +253,14 @@ static bool isRealisablePath(const Transaction & txn, const Path & path)
} }
static PathSet getReferers(const Transaction & txn, const Path & storePath)
{
Paths referers;
nixDB.queryStrings(txn, dbReferers, storePath, referers);
return PathSet(referers.begin(), referers.end());
}
void setReferences(const Transaction & txn, const Path & storePath, void setReferences(const Transaction & txn, const Path & storePath,
const PathSet & references) const PathSet & references)
{ {
@ -260,6 +268,9 @@ void setReferences(const Transaction & txn, const Path & storePath,
throw Error( throw Error(
format("cannot set references for path `%1%' which is invalid and has no substitutes") format("cannot set references for path `%1%' which is invalid and has no substitutes")
% storePath); % storePath);
Paths oldReferences;
nixDB.queryStrings(noTxn, dbReferences, storePath, oldReferences);
nixDB.setStrings(txn, dbReferences, storePath, nixDB.setStrings(txn, dbReferences, storePath,
Paths(references.begin(), references.end())); Paths(references.begin(), references.end()));
@ -268,13 +279,22 @@ void setReferences(const Transaction & txn, const Path & storePath,
for (PathSet::const_iterator i = references.begin(); for (PathSet::const_iterator i = references.begin();
i != references.end(); ++i) i != references.end(); ++i)
{ {
Paths referers; PathSet referers = getReferers(txn, *i);
nixDB.queryStrings(txn, dbReferers, *i, referers); referers.insert(storePath);
PathSet referers2(referers.begin(), referers.end());
referers2.insert(storePath);
nixDB.setStrings(txn, dbReferers, *i, nixDB.setStrings(txn, dbReferers, *i,
Paths(referers2.begin(), referers2.end())); Paths(referers.begin(), referers.end()));
} }
/* Remove referer mappings from paths that are no longer
references. */
for (Paths::iterator i = oldReferences.begin();
i != oldReferences.end(); ++i)
if (references.find(*i) == references.end()) {
PathSet referers = getReferers(txn, *i);
referers.erase(storePath);
nixDB.setStrings(txn, dbReferers, *i,
Paths(referers.begin(), referers.end()));
}
} }
@ -410,14 +430,14 @@ static void invalidatePath(const Path & path, Transaction & txn)
{ {
debug(format("unregistering path `%1%'") % path); debug(format("unregistering path `%1%'") % path);
nixDB.delPair(txn, dbValidPaths, path);
/* Clear the `references' entry for this path, as well as the /* Clear the `references' entry for this path, as well as the
inverse `referers' entries; but only if there are no inverse `referers' entries; but only if there are no
substitutes for this path. This maintains the cleanup substitutes for this path. This maintains the cleanup
invariant. */ invariant. */
if (querySubstitutes(txn, path).size() == 0) if (querySubstitutes(txn, path).size() == 0)
setReferences(txn, path, PathSet()); setReferences(txn, path, PathSet());
nixDB.delPair(txn, dbValidPaths, path);
} }