Patchwork [1,of,2] dagop: simplify dict/set reuse condition in subsetparentswalker

login
register
mail settings
Submitter Yuya Nishihara
Date March 29, 2020, 1:51 p.m.
Message ID <d5aa217ada517aa9d141.1585489864@mimosa>
Download mbox | patch
Permalink /patch/45936/
State Accepted
Headers show

Comments

Yuya Nishihara - March 29, 2020, 1:51 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1585229010 -32400
#      Thu Mar 26 22:23:30 2020 +0900
# Node ID d5aa217ada517aa9d141fbf869aeef8737531ac4
# Parent  30ad0dfa5e61a17c99235665e42e5d338331ae88
dagop: simplify dict/set reuse condition in subsetparentswalker

Prepares for fixing the calculation of p1/p2 sort keys.

With this change, there will be one more copying on merge&fork case. I think
the copying cost is negligible since we'll have to update each item in the
dict on merge/fork.

Patch

diff --git a/mercurial/dagop.py b/mercurial/dagop.py
--- a/mercurial/dagop.py
+++ b/mercurial/dagop.py
@@ -449,12 +449,18 @@  class subsetparentswalker(object):
             # - one of the parents is not active,
             # - or descendants' parents are unresolved.
             if not bothparentsactive or unresolved or resolved:
-                if len(parentrevs) > 1:
+                if len(parentrevs) <= 1:
+                    # can avoid copying the tracking pointer
+                    parentpointers = [(unresolved, resolved)]
+                else:
+                    parentpointers = [
+                        (unresolved, resolved),
+                        (unresolved.copy(), resolved.copy()),
+                    ]
                     # 'rev' is a merge revision. increment the pending count
                     # as the 'unresolved' dict will be duplicated.
                     for r in unresolved:
                         pendingcnt[r] += 1
-                reusable = True  # can we avoid copying the tracking pointer?
                 for i, p in enumerate(parentrevs):
                     assert p < rev
                     heapq.heappush(tovisit, -p)
@@ -462,6 +468,7 @@  class subsetparentswalker(object):
                         # 'p' is a fork revision. concatenate tracking pointers
                         # and decrement the pending count accordingly.
                         knownunresolved, knownresolved = pointers[p]
+                        unresolved, resolved = parentpointers[i]
                         for r, c in unresolved.items():
                             c += [b'1', b'2'][i]
                             if r in knownunresolved:
@@ -475,11 +482,8 @@  class subsetparentswalker(object):
                         # simply propagate the 'resolved' set as deduplicating
                         # 'unresolved' here would be slightly complicated.
                         knownresolved.update(resolved)
-                    elif reusable:
-                        pointers[p] = (unresolved, resolved)
-                        reusable = False
                     else:
-                        pointers[p] = (unresolved.copy(), resolved.copy())
+                        pointers[p] = parentpointers[i]
 
             # then, populate the active parents directly and add the current
             # 'rev' to the tracking pointers of the inactive parents.