about summary refs log tree commit diff
path: root/src/libstore/store.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-08-31T16·13+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-08-31T16·13+0000
commit5c443b65501903f636b00b908bb8eb10e022402e (patch)
tree6eda7c08e475b9a4024e167b18531726d3177299 /src/libstore/store.cc
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/libstore/store.cc')
-rw-r--r--src/libstore/store.cc51
1 files changed, 33 insertions, 18 deletions
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index fdd22c3b88..110ec2b485 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);
 }