hgext3rd/evolve/obsdiscovery.py
changeset 2083 778afb036245
parent 2082 3f787182509f
child 2084 b1f029dcf573
--- a/hgext3rd/evolve/obsdiscovery.py	Thu Mar 09 22:57:41 2017 -0800
+++ b/hgext3rd/evolve/obsdiscovery.py	Fri Mar 10 10:36:46 2017 -0800
@@ -295,10 +295,10 @@
                 toproceed.append(r)
     ranges = list(ranges)
     ranges.sort(key=lambda r: (-len(r), n(r.head)))
-    ui.status('rev         node index size depth\n')
+    ui.status('rev         node index size depth      obshash\n')
     for r in ranges:
-        ui.status('%3d %s %5d %4d %5d\n'
-                  % (r.head, s(n(r.head)), r.index, len(r), r.depth))
+        d = (r.head, s(n(r.head)), r.index, len(r), r.depth, node.short(r.obshash))
+        ui.status('%3d %s %5d %4d %5d %s\n' % d)
 
 _depthcache = {}
 def _depth(repo, rev):
@@ -313,7 +313,6 @@
     """return highest power of two lower than 'i'"""
     return 2 ** int(math.log(i - 1, 2))
 
-
 class _range(object):
 
     def __init__(self, repo, head, index, revs=None):
@@ -395,6 +394,51 @@
             assert standard_start < self.depth
             return self._slicesat(standard_start)
 
+    @util.propertycache
+    def obshash(self):
+        cache = self._repo.obsstore.rangeobshashcache
+        cl = self._repo.changelog
+        n = cl.node
+        obshash = cache.get(self._id)
+        if obshash is not None:
+            return obshash
+        sha = hashlib.sha1()
+        count = 0
+        if len(self) == 1:
+            tmarkers = self._repo.obsstore.relevantmarkers([n(self.head)])
+            bmarkers = []
+            for m in tmarkers:
+                mbin = obsolete._fm1encodeonemarker(m)
+                bmarkers.append(mbin)
+            bmarkers.sort()
+            for m in bmarkers:
+                count += 1
+                sha.update(m)
+        else:
+            for subrange in self.subranges():
+                obshash = subrange.obshash
+                if obshash != node.nullid:
+                    count += 1
+                    sha.update(obshash)
+
+        # note: if there is only one subrange with actual data, we'll just
+        # reuse the same hash.
+        if not count:
+            obshash = node.nullid
+        elif count != 1 or obshash is None:
+            obshash = cache[self._id] = sha.digest()
+        return obshash
+
+@eh.wrapfunction(obsolete.obsstore, '_addmarkers')
+def _addmarkers(orig, obsstore, *args, **kwargs):
+    obsstore.rangeobshashcache.clear()
+    return orig(obsstore, *args, **kwargs)
+
+@eh.addattr(obsolete.obsstore, 'rangeobshashcache')
+@util.propertycache
+def rangeobshashcache(obsstore):
+    return {}
+
 #############################
 ### Tree Hash computation ###
 #############################