mercurial/branchmap.py
author Matt Harbison <matt_harbison@yahoo.com>
Thu, 26 Sep 2024 18:04:31 -0400
changeset 51921 382d9629cede
parent 51901 f0e07efc199f
child 51972 dd3ccda3abc8
permissions -rw-r--r--
interfaces: convert the dirstate zope interface to a Protocol class This is a small trial run for converting the repository interfaces enmasse, in the same series of steps. I'm not sure that this current code is valid (it has zope attribute fields, and it's missing all of the `self` args on its functions, but that was the previous state of things, and made PyCharm really unhappy). But it will be easier to review the repository interface changes if this change is separate from adding `self` and dropping the zope attributes all over. Having an empty constructor in a protocol is weird. I'm not sure if these args should be converted to fields that all subclasses would have, and comments around existing attributes say some should be going away. Comment it out for now so that it's not in the way, but also not forgotten.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18116
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     1
# branchmap.py - logic to computes, maintain and stores branchmap for local repo
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46794
diff changeset
     3
# Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
18116
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     4
#
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
18117
526e7ec5c96e branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18116
diff changeset
     7
51863
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51654
diff changeset
     8
from __future__ import annotations
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    10
from .node import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    11
    bin,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    12
    hex,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    13
    nullrev,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    14
)
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    15
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    16
from typing import (
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
    17
    Any,
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    18
    Callable,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    19
    Dict,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    20
    Iterable,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    21
    List,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    22
    Optional,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    23
    Set,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    24
    TYPE_CHECKING,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    25
    Tuple,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    26
    Union,
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
    27
    cast,
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    28
)
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    29
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    30
from . import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    31
    encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26460
diff changeset
    32
    error,
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
    33
    obsolete,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    34
    scmutil,
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
    35
    util,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    36
)
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    37
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    38
from .utils import (
42138
caebe5e7f4bd repoview: move subsettable in a dedicated module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42134
diff changeset
    39
    repoviewutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    40
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    41
)
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    42
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    43
if TYPE_CHECKING:
46794
e2f7b2695ba1 merge with stable
Matt Harbison <matt_harbison@yahoo.com>
parents: 46780 46685
diff changeset
    44
    from . import localrepo
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
    45
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    46
    assert [localrepo]
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
    47
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
    48
subsettable = repoviewutil.subsettable
42138
caebe5e7f4bd repoview: move subsettable in a dedicated module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42134
diff changeset
    49
18118
e70ff1e599f4 branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18117
diff changeset
    50
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
    51
class BranchMapCache:
41718
a87ca1d7e61d branchmap: improve doc about BranchMapCache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41678
diff changeset
    52
    """mapping of filtered views of repo with their branchcache"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
    53
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    54
    def __init__(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    55
        self._per_filter = {}
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
    56
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    57
    def __getitem__(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    58
        self.updatecache(repo)
51449
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    59
        bcache = self._per_filter[repo.filtername]
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
    60
        bcache._ensure_populated(repo)
51451
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
    61
        assert bcache._filtername == repo.filtername, (
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
    62
            bcache._filtername,
51450
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    63
            repo.filtername,
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    64
        )
51449
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    65
        return bcache
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    66
51537
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
    67
    def update_disk(self, repo, detect_pure_topo=False):
51449
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    68
        """ensure and up-to-date cache is (or will be) written on disk
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    69
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    70
        The cache for this repository view is updated  if needed and written on
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    71
        disk.
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    72
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    73
        If a transaction is in progress, the writing is schedule to transaction
51488
94f821490645 branchcache: change the _delayed flag to an explicit `_dirty` flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51487
diff changeset
    74
        close. See the `BranchMapCache.write_dirty` method.
51449
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    75
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    76
        This method exist independently of __getitem__ as it is sometime useful
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    77
        to signal that we have no intend to use the data in memory yet.
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    78
        """
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    79
        self.updatecache(repo)
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    80
        bcache = self._per_filter[repo.filtername]
51451
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
    81
        assert bcache._filtername == repo.filtername, (
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
    82
            bcache._filtername,
51450
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    83
            repo.filtername,
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    84
        )
51537
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
    85
        if detect_pure_topo:
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
    86
            bcache._detect_pure_topo(repo)
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
    87
        tr = repo.currenttransaction()
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
    88
        if getattr(tr, 'finalized', True):
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
    89
            bcache.sync_disk(repo)
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    90
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    91
    def updatecache(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    92
        """Update the cache for the given filtered view on a repository"""
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    93
        # This can trigger updates for the caches for subsets of the filtered
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    94
        # view, e.g. when there is no cache for this filtered view or the cache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    95
        # is stale.
18121
f8a13f061a8a branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18120
diff changeset
    96
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    97
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    98
        filtername = repo.filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    99
        bcache = self._per_filter.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   100
        if bcache is None or not bcache.validfor(repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   101
            # cache object missing or cache object stale? Read from disk
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   102
            bcache = branch_cache_from_file(repo)
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
   103
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   104
        revs = []
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   105
        if bcache is None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   106
            # no (fresh) cache available anymore, perhaps we can re-use
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   107
            # the cache for a subset, then extend that to add info on missing
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   108
            # revisions.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   109
            subsetname = subsettable.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   110
            if subsetname is not None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   111
                subset = repo.filtered(subsetname)
51494
54f0dd798346 branchcache: do not use `__getitem__` in updatecache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51493
diff changeset
   112
                self.updatecache(subset)
54f0dd798346 branchcache: do not use `__getitem__` in updatecache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51493
diff changeset
   113
                bcache = self._per_filter[subset.filtername].inherit_for(repo)
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   114
                extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   115
                revs.extend(r for r in extrarevs if r <= bcache.tiprev)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   116
            else:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   117
                # nothing to fall back on, start empty.
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   118
                bcache = new_branch_cache(repo)
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
   119
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   120
        revs.extend(cl.revs(start=bcache.tiprev + 1))
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   121
        if revs:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   122
            bcache.update(repo, revs)
18124
79db6d40bced branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18121
diff changeset
   123
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   124
        assert bcache.validfor(repo), filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   125
        self._per_filter[repo.filtername] = bcache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   126
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   127
    def replace(self, repo, remotebranchmap):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   128
        """Replace the branchmap cache for a repo with a branch mapping.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   129
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   130
        This is likely only called during clone with a branch map from a
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   131
        remote.
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   132
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   133
        """
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   134
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   135
        clrev = cl.rev
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   136
        clbranchinfo = cl.branchinfo
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   137
        rbheads = []
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
   138
        closed = set()
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   139
        for bheads in remotebranchmap.values():
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   140
            rbheads += bheads
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   141
            for h in bheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   142
                r = clrev(h)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   143
                b, c = clbranchinfo(r)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   144
                if c:
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
   145
                    closed.add(h)
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   146
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   147
        if rbheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   148
            rtiprev = max((int(clrev(node)) for node in rbheads))
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   149
            cache = new_branch_cache(
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
   150
                repo,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   151
                remotebranchmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   152
                repo[rtiprev].node(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   153
                rtiprev,
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
   154
                closednodes=closed,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   155
            )
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   156
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   157
            # Try to stick it as low as possible
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   158
            # filter above served are unlikely to be fetch from a clone
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   159
            for candidate in (b'base', b'immutable', b'served'):
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   160
                rview = repo.filtered(candidate)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   161
                if cache.validfor(rview):
51489
659f766629c8 branchcache: stop using `copy(…)` in `replace(…)`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51488
diff changeset
   162
                    cache._filtername = candidate
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   163
                    self._per_filter[candidate] = cache
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   164
                    cache._state = STATE_DIRTY
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   165
                    cache.write(rview)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   166
                    return
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   167
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   168
    def clear(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   169
        self._per_filter.clear()
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   170
51488
94f821490645 branchcache: change the _delayed flag to an explicit `_dirty` flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51487
diff changeset
   171
    def write_dirty(self, repo):
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   172
        unfi = repo.unfiltered()
51487
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
   173
        for filtername in repoviewutil.get_ordered_subset():
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
   174
            cache = self._per_filter.get(filtername)
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
   175
            if cache is None:
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
   176
                continue
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   177
            if filtername is None:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   178
                repo = unfi
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   179
            else:
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   180
                repo = unfi.filtered(filtername)
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   181
            cache.sync_disk(repo)
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   182
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   183
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   184
def _unknownnode(node):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   185
    """raises ValueError when branchcache found a node which does not exists"""
49300
227124098e14 py3: use `x.hex()` instead of `pycompat.sysstr(node.hex(x))`
Manuel Jacob <me@manueljacob.de>
parents: 49203
diff changeset
   186
    raise ValueError('node %s does not exist' % node.hex())
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   187
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   188
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   189
def _branchcachedesc(repo):
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   190
    if repo.filtername is not None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   191
        return b'branch cache (%s)' % repo.filtername
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   192
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   193
        return b'branch cache'
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   194
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   195
51454
84fca6d79e25 branchcache: introduce a base class for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51453
diff changeset
   196
class _BaseBranchCache:
20181
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   197
    """A dict like object that hold branches heads cache.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   198
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   199
    This cache is used to avoid costly computations to determine all the
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   200
    branch heads of a repo.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   201
    """
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   202
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   203
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   204
        self,
51287
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   205
        repo: "localrepo.localrepository",
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   206
        entries: Union[
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   207
            Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   208
        ] = (),
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   209
        closed_nodes: Optional[Set[bytes]] = None,
51287
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   210
    ) -> None:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   211
        """hasnode is a function which can be used to verify whether changelog
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   212
        has a given node or not. If it's not provided, we assume that every node
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   213
        we have exists in changelog"""
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   214
        # closednodes is a set of nodes that close their branch. If the branch
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   215
        # cache has been updated, it may contain nodes that are no longer
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   216
        # heads.
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   217
        if closed_nodes is None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   218
            closed_nodes = set()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   219
        self._closednodes = set(closed_nodes)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   220
        self._entries = dict(entries)
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   221
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   222
    def __iter__(self):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   223
        return iter(self._entries)
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   224
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   225
    def __setitem__(self, key, value):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   226
        self._entries[key] = value
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   227
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   228
    def __getitem__(self, key):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   229
        return self._entries[key]
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   230
42113
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   231
    def __contains__(self, key):
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   232
        return key in self._entries
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   233
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   234
    def iteritems(self):
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   235
        return self._entries.items()
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   236
42603
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
   237
    items = iteritems
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
   238
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   239
    def hasbranch(self, label):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   240
        """checks whether a branch of this name exists or not"""
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   241
        return label in self._entries
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   242
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   243
    def _branchtip(self, heads):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   244
        """Return tuple with last open head in heads and false,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   245
        otherwise return last closed head and true."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   246
        tip = heads[-1]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   247
        closed = True
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   248
        for h in reversed(heads):
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   249
            if h not in self._closednodes:
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   250
                tip = h
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   251
                closed = False
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   252
                break
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   253
        return tip, closed
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   254
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   255
    def branchtip(self, branch):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   256
        """Return the tipmost open head on branch head, otherwise return the
20245
4edd179fefb8 help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents: 20190
diff changeset
   257
        tipmost closed head on branch.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   258
        Raise KeyError for unknown branch."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   259
        return self._branchtip(self[branch])[0]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   260
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   261
    def iteropen(self, nodes):
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   262
        return (n for n in nodes if n not in self._closednodes)
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   263
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   264
    def branchheads(self, branch, closed=False):
42112
29c22496dd97 branchmap: prevent using __getitem__() in branchheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42111
diff changeset
   265
        heads = self._entries[branch]
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   266
        if not closed:
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   267
            heads = list(self.iteropen(heads))
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   268
        return heads
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   269
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   270
    def iterbranches(self):
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   271
        for bn, heads in self.items():
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   272
            yield (bn, heads) + self._branchtip(heads)
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   273
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   274
    def iterheads(self):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   275
        """returns all the heads"""
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   276
        return self._entries.values()
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   277
18305
2502a15e033d branchmap: pass revision insteads of changectx to the update function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18234
diff changeset
   278
    def update(self, repo, revgen):
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   279
        """Given a branchhead cache, self, that may have extra nodes or be
20263
ea4996754d91 branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20262
diff changeset
   280
        missing heads, and a generator of nodes that are strictly a superset of
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   281
        heads missing, this function updates self to be correct.
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   282
        """
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
   283
        starttime = util.timer()
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   284
        cl = repo.changelog
51532
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   285
        # Faster than using ctx.obsolete()
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   286
        obsrevs = obsolete.getrevs(repo, b'obsolete')
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   287
        # collect new branch entries
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   288
        newbranches = {}
51534
767b62cb728e branchcache: gather newly closed head in a dedicated set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51533
diff changeset
   289
        new_closed = set()
51533
50850689d3c0 branchcache: gather new obsolete revision in a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51532
diff changeset
   290
        obs_ignored = set()
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
   291
        getbranchinfo = repo.revbranchcache().branchinfo
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   292
        max_rev = -1
18307
0eed2546118a branchmap: Save changectx creation during update
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18305
diff changeset
   293
        for r in revgen:
51532
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   294
            max_rev = max(max_rev, r)
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   295
            if r in obsrevs:
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   296
                # We ignore obsolete changesets as they shouldn't be
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   297
                # considered heads.
51533
50850689d3c0 branchcache: gather new obsolete revision in a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51532
diff changeset
   298
                obs_ignored.add(r)
51532
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   299
                continue
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   300
            branch, closesbranch = getbranchinfo(r)
20262
cf450ee3f8f7 branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20261
diff changeset
   301
            newbranches.setdefault(branch, []).append(r)
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   302
            if closesbranch:
51534
767b62cb728e branchcache: gather newly closed head in a dedicated set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51533
diff changeset
   303
                new_closed.add(r)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   304
        if max_rev < 0:
51486
0ddc34330d41 branchcache: do not accept "empty update"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51468
diff changeset
   305
            msg = "running branchcache.update without revision to update"
0ddc34330d41 branchcache: do not accept "empty update"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51468
diff changeset
   306
            raise error.ProgrammingError(msg)
42214
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   307
51535
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   308
        self._process_new(
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   309
            repo,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   310
            newbranches,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   311
            new_closed,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   312
            obs_ignored,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   313
            max_rev,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   314
        )
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   315
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   316
        self._closednodes.update(cl.node(rev) for rev in new_closed)
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   317
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   318
        duration = util.timer() - starttime
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   319
        repo.ui.log(
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   320
            b'branchcache',
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   321
            b'updated %s in %.4f seconds\n',
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   322
            _branchcachedesc(repo),
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   323
            duration,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   324
        )
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   325
        return max_rev
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   326
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   327
    def _process_new(
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   328
        self,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   329
        repo,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   330
        newbranches,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   331
        new_closed,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   332
        obs_ignored,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   333
        max_rev,
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   334
    ):
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   335
        """update the branchmap from a set of new information"""
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   336
        # Delay fetching the topological heads until they are needed.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   337
        # A repository without non-continous branches can skip this part.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   338
        topoheads = None
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   339
51535
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   340
        cl = repo.changelog
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   341
        getbranchinfo = repo.revbranchcache().branchinfo
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   342
        # Faster than using ctx.obsolete()
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   343
        obsrevs = obsolete.getrevs(repo, b'obsolete')
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   344
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   345
        # If a changeset is visible, its parents must be visible too, so
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   346
        # use the faster unfiltered parent accessor.
51535
03247e37ccf7 branchcache: move the processing of the new data in a dedicated method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51534
diff changeset
   347
        parentrevs = cl._uncheckedparentrevs
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   348
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   349
        for branch, newheadrevs in newbranches.items():
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   350
            # For every branch, compute the new branchheads.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   351
            # A branchhead is a revision such that no descendant is on
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   352
            # the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   353
            #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   354
            # The branchheads are computed iteratively in revision order.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   355
            # This ensures topological order, i.e. parents are processed
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   356
            # before their children. Ancestors are inclusive here, i.e.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   357
            # any revision is an ancestor of itself.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   358
            #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   359
            # Core observations:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   360
            # - The current revision is always a branchhead for the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   361
            #   repository up to that point.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   362
            # - It is the first revision of the branch if and only if
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   363
            #   there was no branchhead before. In that case, it is the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   364
            #   only branchhead as there are no possible ancestors on
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   365
            #   the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   366
            # - If a parent is on the same branch, a branchhead can
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   367
            #   only be an ancestor of that parent, if it is parent
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   368
            #   itself. Otherwise it would have been removed as ancestor
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   369
            #   of that parent before.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   370
            # - Therefore, if all parents are on the same branch, they
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   371
            #   can just be removed from the branchhead set.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   372
            # - If one parent is on the same branch and the other is not
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   373
            #   and there was exactly one branchhead known, the existing
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   374
            #   branchhead can only be an ancestor if it is the parent.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   375
            #   Otherwise it would have been removed as ancestor of
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   376
            #   the parent before. The other parent therefore can't have
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   377
            #   a branchhead as ancestor.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   378
            # - In all other cases, the parents on different branches
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   379
            #   could have a branchhead as ancestor. Those parents are
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   380
            #   kept in the "uncertain" set. If all branchheads are also
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   381
            #   topological heads, they can't have descendants and further
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   382
            #   checks can be skipped. Otherwise, the ancestors of the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   383
            #   "uncertain" set are removed from branchheads.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   384
            #   This computation is heavy and avoided if at all possible.
48718
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   385
            bheads = self._entries.get(branch, [])
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44306
diff changeset
   386
            bheadset = {cl.rev(node) for node in bheads}
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   387
            uncertain = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   388
            for newrev in sorted(newheadrevs):
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   389
                if not bheadset:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   390
                    bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   391
                    continue
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   392
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   393
                parents = [p for p in parentrevs(newrev) if p != nullrev]
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   394
                samebranch = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   395
                otherbranch = set()
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   396
                obsparents = set()
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   397
                for p in parents:
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   398
                    if p in obsrevs:
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   399
                        # We ignored this obsolete changeset earlier, but now
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   400
                        # that it has non-ignored children, we need to make
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   401
                        # sure their ancestors are not considered heads. To
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   402
                        # achieve that, we will simply treat this obsolete
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   403
                        # changeset as a parent from other branch.
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   404
                        obsparents.add(p)
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   405
                    elif p in bheadset or getbranchinfo(p)[0] == branch:
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   406
                        samebranch.add(p)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   407
                    else:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   408
                        otherbranch.add(p)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   409
                if not (len(bheadset) == len(samebranch) == 1):
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   410
                    uncertain.update(otherbranch)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   411
                    uncertain.update(obsparents)
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   412
                bheadset.difference_update(samebranch)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   413
                bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   414
22357
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   415
            if uncertain:
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   416
                if topoheads is None:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   417
                    topoheads = set(cl.headrevs())
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   418
                if bheadset - topoheads:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   419
                    floorrev = min(bheadset)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   420
                    if floorrev <= max(uncertain):
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   421
                        ancestors = set(cl.ancestors(uncertain, floorrev))
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   422
                        bheadset -= ancestors
48718
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   423
            if bheadset:
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   424
                self[branch] = [cl.node(rev) for rev in sorted(bheadset)]
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   425
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   426
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   427
STATE_CLEAN = 1
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   428
STATE_INHERITED = 2
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   429
STATE_DIRTY = 3
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   430
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   431
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   432
class _LocalBranchCache(_BaseBranchCache):
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   433
    """base class of branch-map info for a local repo or repoview"""
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   434
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   435
    _base_filename = None
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   436
    _default_key_hashes: Tuple[bytes] = cast(Tuple[bytes], ())
51460
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
   437
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   438
    def __init__(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   439
        self,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   440
        repo: "localrepo.localrepository",
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   441
        entries: Union[
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   442
            Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   443
        ] = (),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   444
        tipnode: Optional[bytes] = None,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   445
        tiprev: Optional[int] = nullrev,
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   446
        key_hashes: Optional[Tuple[bytes]] = None,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   447
        closednodes: Optional[Set[bytes]] = None,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   448
        hasnode: Optional[Callable[[bytes], bool]] = None,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   449
        verify_node: bool = False,
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   450
        inherited: bool = False,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   451
    ) -> None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   452
        """hasnode is a function which can be used to verify whether changelog
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   453
        has a given node or not. If it's not provided, we assume that every node
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   454
        we have exists in changelog"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   455
        self._filtername = repo.filtername
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   456
        if tipnode is None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   457
            self.tipnode = repo.nullid
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   458
        else:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   459
            self.tipnode = tipnode
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   460
        self.tiprev = tiprev
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   461
        if key_hashes is None:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   462
            self.key_hashes = self._default_key_hashes
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   463
        else:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   464
            self.key_hashes = key_hashes
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   465
        self._state = STATE_CLEAN
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   466
        if inherited:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   467
            self._state = STATE_INHERITED
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   468
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   469
        super().__init__(repo=repo, entries=entries, closed_nodes=closednodes)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   470
        # closednodes is a set of nodes that close their branch. If the branch
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   471
        # cache has been updated, it may contain nodes that are no longer
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   472
        # heads.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   473
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   474
        # Do we need to verify branch at all ?
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   475
        self._verify_node = verify_node
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   476
        # branches for which nodes are verified
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   477
        self._verifiedbranches = set()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   478
        self._hasnode = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   479
        if self._verify_node:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   480
            self._hasnode = repo.changelog.hasnode
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   481
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   482
    def _compute_key_hashes(self, repo) -> Tuple[bytes]:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   483
        raise NotImplementedError
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   484
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   485
    def _ensure_populated(self, repo):
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   486
        """make sure any lazily loaded values are fully populated"""
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   487
51537
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
   488
    def _detect_pure_topo(self, repo) -> None:
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
   489
        pass
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
   490
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   491
    def validfor(self, repo):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   492
        """check that cache contents are valid for (a subset of) this repo
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   493
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   494
        - False when the order of changesets changed or if we detect a strip.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   495
        - True when cache is up-to-date for the current repo or its subset."""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   496
        try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   497
            node = repo.changelog.node(self.tiprev)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   498
        except IndexError:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   499
            # changesets were stripped and now we don't even have enough to
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   500
            # find tiprev
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   501
            return False
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   502
        if self.tipnode != node:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   503
            # tiprev doesn't correspond to tipnode: repo was stripped, or this
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   504
            # repo has a different order of changesets
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   505
            return False
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   506
        repo_key_hashes = self._compute_key_hashes(repo)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   507
        # hashes don't match if this repo view has a different set of filtered
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   508
        # revisions (e.g. due to phase changes) or obsolete revisions (e.g.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   509
        # history was rewritten)
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   510
        return self.key_hashes == repo_key_hashes
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   511
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   512
    @classmethod
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   513
    def fromfile(cls, repo):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   514
        f = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   515
        try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   516
            f = repo.cachevfs(cls._filename(repo))
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   517
            lineiter = iter(f)
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
   518
            init_kwargs = cls._load_header(repo, lineiter)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   519
            bcache = cls(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   520
                repo,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   521
                verify_node=True,
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
   522
                **init_kwargs,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   523
            )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   524
            if not bcache.validfor(repo):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   525
                # invalidate the cache
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   526
                raise ValueError('tip differs')
51461
47752632b4fc branchcache: rename `load` to `_load_heads`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51460
diff changeset
   527
            bcache._load_heads(repo, lineiter)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   528
        except (IOError, OSError):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   529
            return None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   530
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   531
        except Exception as inst:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   532
            if repo.ui.debugflag:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   533
                msg = b'invalid %s: %s\n'
51462
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
   534
                msg %= (
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
   535
                    _branchcachedesc(repo),
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
   536
                    stringutil.forcebytestr(inst),
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   537
                )
51462
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
   538
                repo.ui.debug(msg)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   539
            bcache = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   540
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   541
        finally:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   542
            if f:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   543
                f.close()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   544
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   545
        return bcache
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   546
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
   547
    @classmethod
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
   548
    def _load_header(cls, repo, lineiter) -> "dict[str, Any]":
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   549
        raise NotImplementedError
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
   550
51461
47752632b4fc branchcache: rename `load` to `_load_heads`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51460
diff changeset
   551
    def _load_heads(self, repo, lineiter):
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   552
        """fully loads the branchcache by reading from the file using the line
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   553
        iterator passed"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   554
        for line in lineiter:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   555
            line = line.rstrip(b'\n')
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   556
            if not line:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   557
                continue
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   558
            node, state, label = line.split(b" ", 2)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   559
            if state not in b'oc':
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   560
                raise ValueError('invalid branch state')
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   561
            label = encoding.tolocal(label.strip())
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   562
            node = bin(node)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   563
            self._entries.setdefault(label, []).append(node)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   564
            if state == b'c':
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   565
                self._closednodes.add(node)
42214
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   566
51460
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
   567
    @classmethod
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
   568
    def _filename(cls, repo):
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   569
        """name of a branchcache file for a given repo or repoview"""
51460
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
   570
        filename = cls._base_filename
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   571
        assert filename is not None
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   572
        if repo.filtername:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   573
            filename = b'%s-%s' % (filename, repo.filtername)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   574
        return filename
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   575
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   576
    def inherit_for(self, repo):
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   577
        """return a deep copy of the branchcache object"""
51490
18c2753434f2 branchcache: explicitly assert that copy is always about inheritance
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51489
diff changeset
   578
        assert repo.filtername != self._filtername
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   579
        other = type(self)(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   580
            repo=repo,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   581
            # we always do a shally copy of self._entries, and the values is
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   582
            # always replaced, so no need to deepcopy until the above remains
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   583
            # true.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   584
            entries=self._entries,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   585
            tipnode=self.tipnode,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   586
            tiprev=self.tiprev,
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   587
            key_hashes=self.key_hashes,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   588
            closednodes=set(self._closednodes),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   589
            verify_node=self._verify_node,
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   590
            inherited=True,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   591
        )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   592
        # also copy information about the current verification state
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   593
        other._verifiedbranches = set(self._verifiedbranches)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   594
        return other
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   595
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   596
    def sync_disk(self, repo):
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   597
        """synchronise the on disk file with the cache state
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   598
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   599
        If new value specific to this filter level need to be written, the file
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   600
        will be updated, if the state of the branchcache is inherited from a
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   601
        subset, any stalled on disk file will be deleted.
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   602
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   603
        That method does nothing if there is nothing to do.
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   604
        """
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   605
        if self._state == STATE_DIRTY:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   606
            self.write(repo)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   607
        elif self._state == STATE_INHERITED:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   608
            filename = self._filename(repo)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   609
            repo.cachevfs.tryunlink(filename)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   610
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   611
    def write(self, repo):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   612
        assert self._filtername == repo.filtername, (
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   613
            self._filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   614
            repo.filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   615
        )
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   616
        assert self._state == STATE_DIRTY, self._state
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   617
        # This method should not be called during an open transaction
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   618
        tr = repo.currenttransaction()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   619
        if not getattr(tr, 'finalized', True):
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   620
            msg = "writing branchcache in the middle of a transaction"
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   621
            raise error.ProgrammingError(msg)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   622
        try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   623
            filename = self._filename(repo)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   624
            with repo.cachevfs(filename, b"w", atomictemp=True) as f:
51465
9007387a227c branchcache: move head writing in a `_write_headers` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51464
diff changeset
   625
                self._write_header(f)
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   626
                nodecount = self._write_heads(repo, f)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   627
            repo.ui.log(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   628
                b'branchcache',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   629
                b'wrote %s with %d labels and %d nodes\n',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   630
                _branchcachedesc(repo),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   631
                len(self._entries),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   632
                nodecount,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   633
            )
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   634
            self._state = STATE_CLEAN
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   635
        except (IOError, OSError, error.Abort) as inst:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   636
            # Abort may be raised by read only opener, so log and continue
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   637
            repo.ui.debug(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   638
                b"couldn't write branch cache: %s\n"
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   639
                % stringutil.forcebytestr(inst)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   640
            )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   641
51465
9007387a227c branchcache: move head writing in a `_write_headers` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51464
diff changeset
   642
    def _write_header(self, fp) -> None:
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   643
        raise NotImplementedError
51465
9007387a227c branchcache: move head writing in a `_write_headers` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51464
diff changeset
   644
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   645
    def _write_heads(self, repo, fp) -> int:
51464
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   646
        """write list of heads to a file
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   647
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   648
        Return the number of heads written."""
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   649
        nodecount = 0
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   650
        for label, nodes in sorted(self._entries.items()):
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   651
            label = encoding.fromlocal(label)
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   652
            for node in nodes:
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   653
                nodecount += 1
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   654
                if node in self._closednodes:
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   655
                    state = b'c'
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   656
                else:
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   657
                    state = b'o'
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   658
                fp.write(b"%s %s %s\n" % (hex(node), state, label))
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   659
        return nodecount
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   660
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   661
    def _verifybranch(self, branch):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   662
        """verify head nodes for the given branch."""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   663
        if not self._verify_node:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   664
            return
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   665
        if branch not in self._entries or branch in self._verifiedbranches:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   666
            return
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   667
        assert self._hasnode is not None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   668
        for n in self._entries[branch]:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   669
            if not self._hasnode(n):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   670
                _unknownnode(n)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   671
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   672
        self._verifiedbranches.add(branch)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   673
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   674
    def _verifyall(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   675
        """verifies nodes of all the branches"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   676
        for b in self._entries.keys():
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   677
            if b not in self._verifiedbranches:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   678
                self._verifybranch(b)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   679
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   680
    def __getitem__(self, key):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   681
        self._verifybranch(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   682
        return super().__getitem__(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   683
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   684
    def __contains__(self, key):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   685
        self._verifybranch(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   686
        return super().__contains__(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   687
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   688
    def iteritems(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   689
        self._verifyall()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   690
        return super().iteritems()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   691
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   692
    items = iteritems
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   693
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   694
    def iterheads(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   695
        """returns all the heads"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   696
        self._verifyall()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   697
        return super().iterheads()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   698
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   699
    def hasbranch(self, label):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   700
        """checks whether a branch of this name exists or not"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   701
        self._verifybranch(label)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   702
        return super().hasbranch(label)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   703
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   704
    def branchheads(self, branch, closed=False):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   705
        self._verifybranch(branch)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   706
        return super().branchheads(branch, closed=closed)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   707
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   708
    def update(self, repo, revgen):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   709
        assert self._filtername == repo.filtername, (
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   710
            self._filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   711
            repo.filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   712
        )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   713
        cl = repo.changelog
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   714
        max_rev = super().update(repo, revgen)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   715
        # new tip revision which we found after iterating items from new
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   716
        # branches
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   717
        if max_rev is not None and max_rev > self.tiprev:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   718
            self.tiprev = max_rev
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   719
            self.tipnode = cl.node(max_rev)
51523
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   720
        else:
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   721
            # We should not be here is if this is false
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   722
            assert cl.node(self.tiprev) == self.tipnode
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   723
19838
23386881abeb branchmap: remove the droppednodes logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19837
diff changeset
   724
        if not self.validfor(repo):
51523
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   725
            # the tiprev and tipnode should be aligned, so if the current repo
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   726
            # is not seens as valid this is because old cache key is now
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   727
            # invalid for the repo.
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   728
            #
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   729
            # However. we've just updated the cache and we assume it's valid,
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   730
            # so let's make the cache key valid as well by recomputing it from
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   731
            # the cached data
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   732
            self.key_hashes = self._compute_key_hashes(repo)
51526
a03fa40afd01 filteredhash: rename the filteredhash function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51523
diff changeset
   733
            self.filteredhash = scmutil.combined_filtered_and_obsolete_hash(
a03fa40afd01 filteredhash: rename the filteredhash function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51523
diff changeset
   734
                repo,
a03fa40afd01 filteredhash: rename the filteredhash function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51523
diff changeset
   735
                self.tiprev,
51523
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   736
            )
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   737
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   738
        self._state = STATE_DIRTY
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   739
        tr = repo.currenttransaction()
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   740
        if getattr(tr, 'finalized', True):
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   741
            # Avoid premature writing.
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   742
            #
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   743
            # (The cache warming setup by localrepo will update the file later.)
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   744
            self.write(repo)
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   745
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   746
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   747
def branch_cache_from_file(repo) -> Optional[_LocalBranchCache]:
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   748
    """Build a branch cache from on-disk data if possible
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   749
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   750
    Return a branch cache of the right format depending of the repository.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   751
    """
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   752
    if repo.ui.configbool(b"experimental", b"branch-cache-v3"):
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   753
        return BranchCacheV3.fromfile(repo)
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   754
    else:
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   755
        return BranchCacheV2.fromfile(repo)
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   756
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   757
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   758
def new_branch_cache(repo, *args, **kwargs):
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   759
    """Build a new branch cache from argument
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   760
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   761
    Return a branch cache of the right format depending of the repository.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   762
    """
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   763
    if repo.ui.configbool(b"experimental", b"branch-cache-v3"):
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   764
        return BranchCacheV3(repo, *args, **kwargs)
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   765
    else:
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   766
        return BranchCacheV2(repo, *args, **kwargs)
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   767
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   768
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   769
class BranchCacheV2(_LocalBranchCache):
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   770
    """a branch cache using version 2 of the format on disk
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   771
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   772
    The cache is serialized on disk in the following format:
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   773
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   774
    <tip hex node> <tip rev number> [optional filtered repo hex hash]
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   775
    <branch head hex node> <open/closed state> <branch name>
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   776
    <branch head hex node> <open/closed state> <branch name>
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   777
    ...
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   778
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   779
    The first line is used to check if the cache is still valid. If the
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   780
    branch cache is for a filtered repo view, an optional third hash is
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   781
    included that hashes the hashes of all filtered and obsolete revisions.
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   782
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   783
    The open/closed state is represented by a single letter 'o' or 'c'.
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   784
    This field can be used to avoid changelog reads when determining if a
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   785
    branch head closes a branch or not.
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   786
    """
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   787
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   788
    _base_filename = b"branch2"
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   789
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   790
    @classmethod
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   791
    def _load_header(cls, repo, lineiter) -> "dict[str, Any]":
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   792
        """parse the head of a branchmap file
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   793
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   794
        return parameters to pass to a newly created class instance.
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   795
        """
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   796
        cachekey = next(lineiter).rstrip(b'\n').split(b" ", 2)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   797
        last, lrev = cachekey[:2]
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   798
        last, lrev = bin(last), int(lrev)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   799
        filteredhash = ()
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   800
        if len(cachekey) > 2:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   801
            filteredhash = (bin(cachekey[2]),)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   802
        return {
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   803
            "tipnode": last,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   804
            "tiprev": lrev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   805
            "key_hashes": filteredhash,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   806
        }
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   807
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   808
    def _write_header(self, fp) -> None:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   809
        """write the branch cache header to a file"""
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   810
        cachekey = [hex(self.tipnode), b'%d' % self.tiprev]
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   811
        if self.key_hashes:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   812
            cachekey.append(hex(self.key_hashes[0]))
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   813
        fp.write(b" ".join(cachekey) + b'\n')
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   814
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   815
    def _compute_key_hashes(self, repo) -> Tuple[bytes]:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   816
        """return the cache key hashes that match this repoview state"""
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   817
        filtered_hash = scmutil.combined_filtered_and_obsolete_hash(
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   818
            repo,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   819
            self.tiprev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   820
            needobsolete=True,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   821
        )
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   822
        keys: Tuple[bytes] = cast(Tuple[bytes], ())
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   823
        if filtered_hash is not None:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   824
            keys: Tuple[bytes] = (filtered_hash,)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   825
        return keys
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   826
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   827
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   828
class BranchCacheV3(_LocalBranchCache):
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   829
    """a branch cache using version 3 of the format on disk
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   830
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   831
    This version is still EXPERIMENTAL and the format is subject to changes.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   832
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   833
    The cache is serialized on disk in the following format:
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   834
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   835
    <cache-key-xxx>=<xxx-value> <cache-key-yyy>=<yyy-value> […]
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   836
    <branch head hex node> <open/closed state> <branch name>
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   837
    <branch head hex node> <open/closed state> <branch name>
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   838
    ...
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   839
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   840
    The first line is used to check if the cache is still valid. It is a series
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   841
    of key value pair. The following key are recognized:
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   842
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   843
    - tip-rev: the rev-num of the tip-most revision seen by this cache
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   844
    - tip-node: the node-id of the tip-most revision sen by this cache
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   845
    - filtered-hash: the hash of all filtered revisions (before tip-rev)
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   846
                     ignored by this cache.
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   847
    - obsolete-hash: the hash of all non-filtered obsolete revisions (before
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   848
                     tip-rev) ignored by this cache.
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   849
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   850
    The tip-rev is used to know how far behind the value in the file are
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   851
    compared to the current repository state.
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   852
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   853
    The tip-node, filtered-hash and obsolete-hash are used to detect if this
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   854
    cache can be used for this repository state at all.
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   855
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   856
    The open/closed state is represented by a single letter 'o' or 'c'.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   857
    This field can be used to avoid changelog reads when determining if a
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   858
    branch head closes a branch or not.
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   859
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   860
    Topological heads are not included in the listing and should be dispatched
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   861
    on the right branch at read time. Obsolete topological heads should be
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   862
    ignored.
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   863
    """
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   864
51646
f02ec1ecb3bf branch3: use an explicitely experimental name for files
Raphaël Gomès <rgomes@octobus.net>
parents: 51537
diff changeset
   865
    _base_filename = b"branch3-exp"
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   866
    _default_key_hashes = (None, None)
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   867
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   868
    def __init__(self, *args, pure_topo_branch=None, **kwargs):
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   869
        super().__init__(*args, **kwargs)
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   870
        self._pure_topo_branch = pure_topo_branch
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   871
        self._needs_populate = self._pure_topo_branch is not None
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   872
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   873
    def inherit_for(self, repo):
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   874
        new = super().inherit_for(repo)
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   875
        new._pure_topo_branch = self._pure_topo_branch
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   876
        new._needs_populate = self._needs_populate
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   877
        return new
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   878
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   879
    def _get_topo_heads(self, repo):
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   880
        """returns the topological head of a repoview content up to self.tiprev"""
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   881
        cl = repo.changelog
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   882
        if self.tiprev == nullrev:
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   883
            return []
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   884
        elif self.tiprev == cl.tiprev():
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   885
            return cl.headrevs()
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   886
        else:
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   887
            # XXX passing tiprev as ceiling of cl.headrevs could be faster
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   888
            heads = cl.headrevs(cl.revs(stop=self.tiprev))
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   889
            return heads
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   890
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   891
    def _write_header(self, fp) -> None:
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   892
        cache_keys = {
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   893
            b"tip-node": hex(self.tipnode),
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   894
            b"tip-rev": b'%d' % self.tiprev,
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   895
        }
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   896
        if self.key_hashes:
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   897
            if self.key_hashes[0] is not None:
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   898
                cache_keys[b"filtered-hash"] = hex(self.key_hashes[0])
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   899
            if self.key_hashes[1] is not None:
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   900
                cache_keys[b"obsolete-hash"] = hex(self.key_hashes[1])
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   901
        if self._pure_topo_branch is not None:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   902
            cache_keys[b"topo-mode"] = b"pure"
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   903
        pieces = (b"%s=%s" % i for i in sorted(cache_keys.items()))
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   904
        fp.write(b" ".join(pieces) + b'\n')
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   905
        if self._pure_topo_branch is not None:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   906
            label = encoding.fromlocal(self._pure_topo_branch)
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   907
            fp.write(label + b'\n')
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   908
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   909
    def _write_heads(self, repo, fp) -> int:
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   910
        """write list of heads to a file
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   911
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   912
        Return the number of heads written."""
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   913
        nodecount = 0
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   914
        topo_heads = None
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   915
        if self._pure_topo_branch is None:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   916
            topo_heads = set(self._get_topo_heads(repo))
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   917
        to_rev = repo.changelog.index.rev
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   918
        for label, nodes in sorted(self._entries.items()):
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   919
            if label == self._pure_topo_branch:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   920
                # not need to write anything the header took care of that
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   921
                continue
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   922
            label = encoding.fromlocal(label)
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   923
            for node in nodes:
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   924
                if topo_heads is not None:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   925
                    rev = to_rev(node)
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   926
                    if rev in topo_heads:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   927
                        continue
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   928
                if node in self._closednodes:
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   929
                    state = b'c'
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   930
                else:
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   931
                    state = b'o'
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   932
                nodecount += 1
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   933
                fp.write(b"%s %s %s\n" % (hex(node), state, label))
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   934
        return nodecount
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   935
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   936
    @classmethod
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   937
    def _load_header(cls, repo, lineiter):
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   938
        header_line = next(lineiter)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   939
        pieces = header_line.rstrip(b'\n').split(b" ")
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   940
        cache_keys = dict(p.split(b'=', 1) for p in pieces)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   941
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   942
        args = {}
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   943
        filtered_hash = None
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   944
        obsolete_hash = None
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   945
        has_pure_topo_heads = False
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   946
        for k, v in cache_keys.items():
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   947
            if k == b"tip-rev":
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   948
                args["tiprev"] = int(v)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   949
            elif k == b"tip-node":
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   950
                args["tipnode"] = bin(v)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   951
            elif k == b"filtered-hash":
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   952
                filtered_hash = bin(v)
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   953
            elif k == b"obsolete-hash":
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   954
                obsolete_hash = bin(v)
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   955
            elif k == b"topo-mode":
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   956
                if v == b"pure":
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   957
                    has_pure_topo_heads = True
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   958
                else:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   959
                    msg = b"unknown topo-mode: %r" % v
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   960
                    raise ValueError(msg)
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   961
            else:
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   962
                msg = b"unknown cache key: %r" % k
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   963
                raise ValueError(msg)
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   964
        args["key_hashes"] = (filtered_hash, obsolete_hash)
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   965
        if has_pure_topo_heads:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   966
            pure_line = next(lineiter).rstrip(b'\n')
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   967
            args["pure_topo_branch"] = encoding.tolocal(pure_line)
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   968
        return args
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   969
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   970
    def _load_heads(self, repo, lineiter):
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   971
        """fully loads the branchcache by reading from the file using the line
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   972
        iterator passed"""
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   973
        super()._load_heads(repo, lineiter)
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   974
        if self._pure_topo_branch is not None:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   975
            # no need to read the repository heads, we know their value already.
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   976
            return
51531
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   977
        cl = repo.changelog
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   978
        getbranchinfo = repo.revbranchcache().branchinfo
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   979
        obsrevs = obsolete.getrevs(repo, b'obsolete')
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   980
        to_node = cl.node
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   981
        touched_branch = set()
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   982
        for head in self._get_topo_heads(repo):
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   983
            if head in obsrevs:
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   984
                continue
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   985
            node = to_node(head)
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   986
            branch, closed = getbranchinfo(head)
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   987
            self._entries.setdefault(branch, []).append(node)
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   988
            if closed:
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   989
                self._closednodes.add(node)
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   990
            touched_branch.add(branch)
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   991
        to_rev = cl.index.rev
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   992
        for branch in touched_branch:
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   993
            self._entries[branch].sort(key=to_rev)
f85f23f1479b branchcache: skip entries that are topological heads in the on disk file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51529
diff changeset
   994
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   995
    def _compute_key_hashes(self, repo) -> Tuple[bytes]:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   996
        """return the cache key hashes that match this repoview state"""
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   997
        return scmutil.filtered_and_obsolete_hash(
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   998
            repo,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   999
            self.tiprev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
  1000
        )
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
  1001
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1002
    def _process_new(
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1003
        self,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1004
        repo,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1005
        newbranches,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1006
        new_closed,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1007
        obs_ignored,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1008
        max_rev,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1009
    ) -> None:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1010
        if (
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1011
            # note: the check about `obs_ignored` is too strict as the
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1012
            # obsolete revision could be non-topological, but lets keep
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1013
            # things simple for now
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1014
            #
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1015
            # The same apply to `new_closed` if the closed changeset are
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1016
            # not a head, we don't care that it is closed, but lets keep
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1017
            # things simple here too.
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1018
            not (obs_ignored or new_closed)
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1019
            and (
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1020
                not newbranches
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1021
                or (
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1022
                    len(newbranches) == 1
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1023
                    and (
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1024
                        self.tiprev == nullrev
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1025
                        or self._pure_topo_branch in newbranches
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1026
                    )
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1027
                )
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1028
            )
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1029
        ):
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1030
            if newbranches:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1031
                assert len(newbranches) == 1
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1032
                self._pure_topo_branch = list(newbranches.keys())[0]
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1033
                self._needs_populate = True
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1034
                self._entries.pop(self._pure_topo_branch, None)
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1035
            return
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1036
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1037
        self._ensure_populated(repo)
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1038
        self._pure_topo_branch = None
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1039
        super()._process_new(
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1040
            repo,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1041
            newbranches,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1042
            new_closed,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1043
            obs_ignored,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1044
            max_rev,
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1045
        )
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1046
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1047
    def _ensure_populated(self, repo):
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1048
        """make sure any lazily loaded values are fully populated"""
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1049
        if self._needs_populate:
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1050
            assert self._pure_topo_branch is not None
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1051
            cl = repo.changelog
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1052
            to_node = cl.node
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1053
            topo_heads = self._get_topo_heads(repo)
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1054
            heads = [to_node(r) for r in topo_heads]
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1055
            self._entries[self._pure_topo_branch] = heads
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1056
            self._needs_populate = False
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
  1057
51537
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1058
    def _detect_pure_topo(self, repo) -> None:
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1059
        if self._pure_topo_branch is not None:
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1060
            # we are pure topological already
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1061
            return
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1062
        to_node = repo.changelog.node
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1063
        topo_heads = [to_node(r) for r in self._get_topo_heads(repo)]
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1064
        if any(n in self._closednodes for n in topo_heads):
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1065
            return
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1066
        for branch, heads in self._entries.items():
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1067
            if heads == topo_heads:
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1068
                self._pure_topo_branch = branch
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1069
                break
4a8bb136ee77 branchcache: allow to detect "pure topological case" for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51536
diff changeset
  1070
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
  1071
51454
84fca6d79e25 branchcache: introduce a base class for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51453
diff changeset
  1072
class remotebranchcache(_BaseBranchCache):
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
  1073
    """Branchmap info for a remote connection, should not write locally"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1074
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1075
    def __init__(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1076
        self,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1077
        repo: "localrepo.localrepository",
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1078
        entries: Union[
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1079
            Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1080
        ] = (),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1081
        closednodes: Optional[Set[bytes]] = None,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1082
    ) -> None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1083
        super().__init__(repo=repo, entries=entries, closed_nodes=closednodes)