aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-08-31 16:13:10 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-08-31 16:13:10 +0000
commit5c443b65501903f636b00b908bb8eb10e022402e (patch)
tree6eda7c08e475b9a4024e167b18531726d3177299 /src
parentc25f2883b149bf71931f963d29241fe012360633 (diff)
* Main the `substitutes-rev' table again, but now in a way that
doesn't take \Theta(n^2) space/time complexity.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/store.cc51
-rw-r--r--src/libstore/store.hh5
-rw-r--r--src/nix-store/main.cc5
3 files changed, 40 insertions, 21 deletions
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index fdd22c3b8..110ec2b48 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -322,29 +322,44 @@ static void writeSubstitutes(const Transaction & txn,
}
-void registerSubstitute(const Transaction & txn,
- const Path & srcPath, const Substitute & sub)
+typedef map<Path, Paths> SubstitutesRev;
+
+
+void registerSubstitutes(const Transaction & txn,
+ const SubstitutePairs & subPairs)
{
- assertStorePath(srcPath);
- assertStorePath(sub.storeExpr);
+ SubstitutesRev revMap;
- Substitutes subs = readSubstitutes(txn, srcPath);
-
- if (find(subs.begin(), subs.end(), sub) != subs.end()) {
- /* Nothing to do if the substitute is already known. */
- return;
- }
- subs.push_front(sub); /* new substitutes take precedence */
+ for (SubstitutePairs::const_iterator i = subPairs.begin();
+ i != subPairs.end(); ++i)
+ {
+ const Path & srcPath(i->first);
+ const Substitute & sub(i->second);
- writeSubstitutes(txn, srcPath, subs);
+ assertStorePath(srcPath);
+ assertStorePath(sub.storeExpr);
- Paths revs;
- nixDB.queryStrings(txn, dbSubstitutesRev, sub.storeExpr, revs);
- if (find(revs.begin(), revs.end(), srcPath) == revs.end())
- revs.push_back(srcPath);
+ Substitutes subs = readSubstitutes(txn, srcPath);
+
+ /* New substitutes take precedence over old ones. If the
+ substitute is already present, it's moved to the front. */
+ remove(subs.begin(), subs.end(), sub);
+ subs.push_front(sub);
+
+ writeSubstitutes(txn, srcPath, subs);
+
+ Paths & revs = revMap[sub.storeExpr];
+ if (revs.empty())
+ nixDB.queryStrings(txn, dbSubstitutesRev, sub.storeExpr, revs);
+ if (find(revs.begin(), revs.end(), srcPath) == revs.end())
+ revs.push_back(srcPath);
+ }
- // !!! O(n^2) complexity in building this
- // nixDB.setStrings(txn, dbSubstitutesRev, sub.storeExpr, revs);
+ /* Re-write the reverse mapping in one go to prevent Theta(n^2)
+ performance. (This would occur because the data fields of the
+ `substitutes-rev' table are lists). */
+ for (SubstitutesRev::iterator i = revMap.begin(); i != revMap.end(); ++i)
+ nixDB.setStrings(txn, dbSubstitutesRev, i->first, i->second);
}
diff --git a/src/libstore/store.hh b/src/libstore/store.hh
index 68f7d6190..10d2890b8 100644
--- a/src/libstore/store.hh
+++ b/src/libstore/store.hh
@@ -66,8 +66,9 @@ bool querySuccessor(const Path & srcPath, Path & sucPath);
Paths queryPredecessors(const Path & sucPath);
/* Register a substitute. */
-void registerSubstitute(const Transaction & txn,
- const Path & srcPath, const Substitute & sub);
+typedef list<pair<Path, Substitute> > SubstitutePairs;
+void registerSubstitutes(const Transaction & txn,
+ const SubstitutePairs & subPairs);
/* Return the substitutes expression for the given path. */
Substitutes querySubstitutes(const Path & srcPath);
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index e9948c7cf..a8acd30c7 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -158,6 +158,7 @@ static void opSubstitute(Strings opFlags, Strings opArgs)
if (!opArgs.empty())
throw UsageError("no arguments expected");
+ SubstitutePairs subPairs;
Transaction txn;
createStoreTransaction(txn);
@@ -179,9 +180,11 @@ static void opSubstitute(Strings opFlags, Strings opArgs)
sub.args.push_back(s);
}
if (!cin || cin.eof()) throw Error("missing input");
- registerSubstitute(txn, srcPath, sub);
+ subPairs.push_back(pair<Path, Substitute>(srcPath, sub));
}
+ registerSubstitutes(txn, subPairs);
+
txn.commit();
}