mercurial/graphmod.py
changeset 23566 fee7a30cfdf5
parent 23565 996c01bfbec4
child 23567 1f080c9c6a35
equal deleted inserted replaced
23565:996c01bfbec4 23566:fee7a30cfdf5
   108     # be easy. The iteration will have to be done using both input revision and
   108     # be easy. The iteration will have to be done using both input revision and
   109     # parents (see cl.ancestors function + a few tweaks) but only revisions
   109     # parents (see cl.ancestors function + a few tweaks) but only revisions
   110     # parts of the initial set should be emitted.
   110     # parts of the initial set should be emitted.
   111     groups = [([], unblocked)]
   111     groups = [([], unblocked)]
   112     for current in revs:
   112     for current in revs:
   113         # Look for a subgroup blocked, waiting for the current revision.
   113         if True:
   114         matching = [i for i, g in enumerate(groups) if current in g[1]]
   114             # Seek for a subgroup blocked, waiting for the current revision.
   115 
   115             matching = [i for i, g in enumerate(groups) if current in g[1]]
   116         if matching:
   116 
   117             # The main idea is to gather together all sets that await on the
   117             if matching:
   118             # same revision.
   118                 # The main idea is to gather together all sets that await on
       
   119                 # the same revision.
       
   120                 #
       
   121                 # This merging is done at the time we are about to add this
       
   122                 # common awaited to the subgroup for simplicity purpose. Such
       
   123                 # merge could happen sooner when we update the "blocked" set of
       
   124                 # revision.
       
   125                 #
       
   126                 # We also always keep the oldest subgroup first. We can
       
   127                 # probably improve the behavior by having the longuest set
       
   128                 # first. That way, graph algorythms could minimise the length
       
   129                 # of parallele lines their draw. This is currently not done.
       
   130                 targetidx = matching.pop(0)
       
   131                 trevs, tparents = groups[targetidx]
       
   132                 for i in matching:
       
   133                     gr = groups[i]
       
   134                     trevs.extend(gr[0])
       
   135                     tparents |= gr[1]
       
   136                 # delete all merged subgroups (but the one we keep) (starting
       
   137                 # from the last subgroup for performance and sanity reason)
       
   138                 for i in reversed(matching):
       
   139                     del groups[i]
       
   140             else:
       
   141                 # This is a new head. We create a new subgroup for it.
       
   142                 targetidx = len(groups)
       
   143                 groups.append(([], set([current])))
       
   144 
       
   145             gr = groups[targetidx]
       
   146 
       
   147             # We now adds the current nodes to this subgroups. This is done
       
   148             # after the subgroup merging because all elements from a subgroup
       
   149             # that relied on this rev must preceed it.
   119             #
   150             #
   120             # This merging is done at the time we are about to add this common
   151             # we also update the <parents> set to includes the parents on the
   121             # awaited to the subgroup for simplicity purpose. Such merge could
   152             # new nodes.
   122             # happen sooner when we update the "blocked" set of revision.
   153             gr[0].append(current)
       
   154             gr[1].remove(current)
       
   155             gr[1].update([p for p in parentsfunc(current) if p > nullrev])
       
   156 
       
   157             # Look for a subgroup to display
   123             #
   158             #
   124             # We also always keep the oldest subgroup first. We can probably
   159             # When unblocked is empty (if clause), We are not waiting over any
   125             # improve the behavior by having the longuest set first. That way,
   160             # revision during the first iteration (if no priority was given) or
   126             # graph algorythms could minimise the length of parallele lines
   161             # if we outputed a whole disconnected sets of the graph (reached a
   127             # their draw. This is currently not done.
   162             # root).  In that case we arbitrarily takes the oldest known
   128             targetidx = matching.pop(0)
   163             # subgroup. The heuristique could probably be better.
   129             trevs, tparents = groups[targetidx]
   164             #
   130             for i in matching:
   165             # Otherwise (elif clause) this mean we have some emitted revision.
   131                 gr = groups[i]
   166             # if the subgroup awaits on the same revision that the outputed
   132                 trevs.extend(gr[0])
   167             # ones, we can safely output it.
   133                 tparents |= gr[1]
   168             if not unblocked:
   134             # delete all merged subgroups (but the one we keep)
   169                 if len(groups) > 1:  # display other subset
   135             # (starting from the last subgroup for performance and sanity reason)
   170                     targetidx = 1
   136             for i in reversed(matching):
   171                     gr = groups[1]
   137                 del groups[i]
   172             elif not gr[1] & unblocked:
   138         else:
   173                 gr = None
   139             # This is a new head. We create a new subgroup for it.
   174 
   140             targetidx = len(groups)
   175             if gr is not None:
   141             groups.append(([], set([current])))
   176                 # update the set of awaited revisions with the one from the
   142 
   177                 # subgroup
   143         gr = groups[targetidx]
   178                 unblocked |= gr[1]
   144 
   179                 # output all revisions in the subgroup
   145         # We now adds the current nodes to this subgroups. This is done after
   180                 for r in gr[0]:
   146         # the subgroup merging because all elements from a subgroup that relied
   181                     yield r
   147         # on this rev must preceed it.
   182                 # delete the subgroup that you just output
   148         #
   183                 # unless it is groups[0] in which case you just empty it.
   149         # we also update the <parents> set to includes the parents on the
   184                 if targetidx:
   150         # new nodes.
   185                     del groups[targetidx]
   151         gr[0].append(current)
   186                 else:
   152         gr[1].remove(current)
   187                     gr[0][:] = []
   153         gr[1].update([p for p in parentsfunc(current) if p > nullrev])
       
   154 
       
   155         # Look for a subgroup to display
       
   156         #
       
   157         # When unblocked is empty (if clause), We are not waiting over any
       
   158         # revision during the first iteration (if no priority was given) or if
       
   159         # we outputed a whole disconnected sets of the graph (reached a root).
       
   160         # In that case we arbitrarily takes the oldest known subgroup. The
       
   161         # heuristique could probably be better.
       
   162         #
       
   163         # Otherwise (elif clause) this mean we have some emitted revision.  if
       
   164         # the subgroup awaits on the same revision that the outputed ones, we
       
   165         # can safely output it.
       
   166         if not unblocked:
       
   167             if len(groups) > 1:  # display other subset
       
   168                 targetidx = 1
       
   169                 gr = groups[1]
       
   170         elif not gr[1] & unblocked:
       
   171             gr = None
       
   172 
       
   173         if gr is not None:
       
   174             # update the set of awaited revisions with the one from the
       
   175             # subgroup
       
   176             unblocked |= gr[1]
       
   177             # output all revisions in the subgroup
       
   178             for r in gr[0]:
       
   179                 yield r
       
   180             # delete the subgroup that you just output
       
   181             # unless it is groups[0] in which case you just empty it.
       
   182             if targetidx:
       
   183                 del groups[targetidx]
       
   184             else:
       
   185                 gr[0][:] = []
       
   186 
   188 
   187 def dagwalker(repo, revs):
   189 def dagwalker(repo, revs):
   188     """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
   190     """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
   189 
   191 
   190     This generator function walks through revisions (which should be ordered
   192     This generator function walks through revisions (which should be ordered