Patchwork [1,of,3] phases: add a getrevs method to phasecache

login
register
mail settings
Submitter Jun Wu
Date Feb. 10, 2017, 2:34 p.m.
Message ID <1d7a184bb013a1a6f6b9.1486737257@localhost.localdomain>
Download mbox | patch
Permalink /patch/18395/
State Changes Requested
Delegated to: Yuya Nishihara
Headers show

Comments

Jun Wu - Feb. 10, 2017, 2:34 p.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1486731527 28800
#      Fri Feb 10 04:58:47 2017 -0800
# Node ID 1d7a184bb013a1a6f6b92d1f6d89406a7254ba2b
# Parent  dd14ece7cb20d8f3c764b17d2edc9ee646a27f2f
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 1d7a184bb013
phases: add a getrevs method to phasecache

This is part of a refactoring that moves some phase query optimization from
revset.py to phases.py.

The motivation behind this is chg repo preloading - to preload the obsstore,
the calculation functions (obsolete.getrevs) need to be called. Currently those
functions use revsets (repo.revs), which is an overkill and requires a lot
of dependencies to be available on the repo object. The reality is, the
calculation only needs to query phase revisions. So let's make it use phases
instead of revset.

This patch adds a getrevs method so phasecache users could get a set of
revisions easily. Previously there is no API on phasecache to access
"_phasesets" and other code is accessing the private field "_phasesets"
directly.

Patch

diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -171,4 +171,24 @@  class phasecache(object):
             self.opener = repo.svfs
 
+    def getrevs(self, repo, phases):
+        """return a set of revision numbers for the given phases"""
+        result = set()
+        slowphases = set(phases) # for slow path testing
+        self.loadphaserevs(repo) # ensure phase's sets are loaded
+
+        # fast path - use _phasesets
+        for phase in phases:
+            if self._phasesets and self._phasesets[phase] is not None:
+                result.update(self._phasesets[phase])
+                slowphases.remove(phase)
+        # slow path - enumerate all revisions
+        if slowphases:
+            result.update(r for r, p in enumerate(self._phaserevs)
+                          if p in slowphases)
+
+        if repo.changelog.filteredrevs:
+            result -= repo.changelog.filteredrevs
+        return result
+
     def copy(self):
         # Shallow copy meant to ensure isolation in