obshashrange: less brutal reset when receiving markers on existing node
authorPierre-Yves David <pierre-yves.david@octobus.net>
Thu, 21 Dec 2017 04:14:05 +0100
changeset 3355 c261eece1eab
parent 3354 32e7ceaf1d82
child 3356 24b72cbc486f
obshashrange: less brutal reset when receiving markers on existing node We now target the affected ranges only. The implementation is still slow but that should be better than what we had before.
hgext3rd/evolve/obsdiscovery.py
hgext3rd/evolve/stablerangecache.py
--- a/hgext3rd/evolve/obsdiscovery.py	Thu Dec 21 04:39:45 2017 +0100
+++ b/hgext3rd/evolve/obsdiscovery.py	Thu Dec 21 04:14:05 2017 +0100
@@ -353,6 +353,7 @@
 _queryobshash = "SELECT obshash FROM obshashrange WHERE (rev = ? AND idx = ?);"
 
 _reset = "DELETE FROM obshashrange;"
+_delete = "DELETE FROM obshashrange WHERE (rev = ? AND idx = ?);"
 
 class _obshashcache(obscache.dualsourcecache):
 
@@ -441,6 +442,11 @@
             con = self._con
             if con is not None:
                 con.execute(_reset)
+
+            ranges = repo.stablerange.contains(repo, affected)
+
+            con.executemany(_delete, ranges)
+
             # rewarm key revisions
             #
             # (The current invalidation is too wide, but rewarming every single
@@ -448,7 +454,7 @@
             newrevs = []
             stop = self._cachekey[0] # tiprev
             for h in repo.filtered('immutable').changelog.headrevs():
-                if h <= stop:
+                if h <= stop and h in affected:
                     newrevs.append(h)
             newrevs.extend(revs)
             revs = newrevs
--- a/hgext3rd/evolve/stablerangecache.py	Thu Dec 21 04:39:45 2017 +0100
+++ b/hgext3rd/evolve/stablerangecache.py	Thu Dec 21 04:14:05 2017 +0100
@@ -109,6 +109,10 @@
                      FROM subranges
                      WHERE (suprev = ? AND supidx = ?)
                      ORDER BY listidx;"""
+_querysuperranges = """SELECT suprev, supidx
+                       FROM subranges
+                       WHERE (subrev = ? AND subidx = ?)
+                       ORDER BY listidx;"""
 
 class stablerangesqlbase(stablerange.stablerangecached):
     """class that can handle all the bits needed to store range into sql
@@ -128,6 +132,23 @@
         self._ondisktipnode = None
         self._unsavedsubranges = {}
 
+    def contains(self, repo, revs):
+        new = set()
+        known = set()
+        depth = repo.depthcache.get
+        for r in revs:
+            new.add((r, depth(r) - 1))
+            new.add((r, 0))
+        con = self._con
+        while new:
+            # many execute is not efficient
+            next = new.pop()
+            known.add(next)
+            ranges = set(con.execute(_querysuperranges, next).fetchall())
+            new.update(ranges)
+            new -= known
+        return sorted(known)
+
     def _getsub(self, rangeid):
         # 1) check the in memory cache
         # 2) check the sqlcaches (and warm in memory cache we want we find)