mercurial/branchmap.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 07 Mar 2024 04:15:23 +0100
changeset 51536 718f28ea3af4
parent 51535 03247e37ccf7
child 51537 4a8bb136ee77
permissions -rw-r--r--
branchcache: add a "pure topological head" fast path In a narrow but actually quick common case, all topological heads are all on the same branch and all open. In this case, computing the branch map is very simple. We can quickly detect situation where this situation will not change. So we update the V3 format to be able to express this situation and upgrade the update code to detect we remains in that mode. The branch cache is populated with the actual value when the branch map is accessed, but the update_disk method can do the update without needing to populate it.
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
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     8
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
import struct
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    10
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    11
from .node import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    12
    bin,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    13
    hex,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    14
    nullrev,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    15
)
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    16
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    17
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
    18
    Any,
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    19
    Callable,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    20
    Dict,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    21
    Iterable,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    22
    List,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    23
    Optional,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    24
    Set,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    25
    TYPE_CHECKING,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    26
    Tuple,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    27
    Union,
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
    28
    cast,
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    29
)
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    30
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    31
from . import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    32
    encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26460
diff changeset
    33
    error,
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
    34
    obsolete,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    35
    scmutil,
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
    36
    util,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    37
)
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    38
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    39
from .utils import (
42138
caebe5e7f4bd repoview: move subsettable in a dedicated module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42134
diff changeset
    40
    repoviewutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    41
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    42
)
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    43
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    44
if TYPE_CHECKING:
46794
e2f7b2695ba1 merge with stable
Matt Harbison <matt_harbison@yahoo.com>
parents: 46780 46685
diff changeset
    45
    from . import localrepo
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
    46
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    47
    assert [localrepo]
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
    48
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
    49
subsettable = repoviewutil.subsettable
42138
caebe5e7f4bd repoview: move subsettable in a dedicated module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42134
diff changeset
    50
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    51
calcsize = struct.calcsize
31370
906be86990c4 rbc: use struct unpack_from and pack_into instead of unpack and pack
Mads Kiilerich <madski@unity3d.com>
parents: 31360
diff changeset
    52
pack_into = struct.pack_into
906be86990c4 rbc: use struct unpack_from and pack_into instead of unpack and pack
Mads Kiilerich <madski@unity3d.com>
parents: 31360
diff changeset
    53
unpack_from = struct.unpack_from
18117
526e7ec5c96e branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18116
diff changeset
    54
18118
e70ff1e599f4 branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18117
diff changeset
    55
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
    56
class BranchMapCache:
41718
a87ca1d7e61d branchmap: improve doc about BranchMapCache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41678
diff changeset
    57
    """mapping of filtered views of repo with their branchcache"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
    58
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    59
    def __init__(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    60
        self._per_filter = {}
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
    61
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    62
    def __getitem__(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    63
        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
    64
        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
    65
        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
    66
        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
    67
            bcache._filtername,
51450
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    68
            repo.filtername,
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    69
        )
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
    70
        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
    71
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
    def update_disk(self, 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
    73
        """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
    74
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
        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
    76
        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
    77
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
        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
    79
        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
    80
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    81
        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
    82
        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
    83
        """
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
    84
        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
    85
        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
    86
        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
    87
            bcache._filtername,
51450
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    88
            repo.filtername,
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    89
        )
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
    90
        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
    91
        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
    92
            bcache.sync_disk(repo)
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    93
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    94
    def updatecache(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    95
        """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
    96
        # 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
    97
        # 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
    98
        # is stale.
18121
f8a13f061a8a branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18120
diff changeset
    99
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   100
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   101
        filtername = repo.filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   102
        bcache = self._per_filter.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   103
        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
   104
            # 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
   105
            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
   106
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   107
        revs = []
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   108
        if bcache is None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   109
            # 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
   110
            # 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
   111
            # revisions.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   112
            subsetname = subsettable.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   113
            if subsetname is not None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   114
                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
   115
                self.updatecache(subset)
54f0dd798346 branchcache: do not use `__getitem__` in updatecache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51493
diff changeset
   116
                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
   117
                extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   118
                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
   119
            else:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   120
                # 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
   121
                bcache = new_branch_cache(repo)
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
   122
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   123
        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
   124
        if revs:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   125
            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
   126
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   127
        assert bcache.validfor(repo), filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   128
        self._per_filter[repo.filtername] = bcache
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
    def replace(self, repo, remotebranchmap):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   131
        """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
   132
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   133
        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
   134
        remote.
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   135
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   136
        """
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   137
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   138
        clrev = cl.rev
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   139
        clbranchinfo = cl.branchinfo
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   140
        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
   141
        closed = set()
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   142
        for bheads in remotebranchmap.values():
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   143
            rbheads += bheads
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   144
            for h in bheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   145
                r = clrev(h)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   146
                b, c = clbranchinfo(r)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   147
                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
   148
                    closed.add(h)
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   149
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   150
        if rbheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   151
            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
   152
            cache = new_branch_cache(
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
   153
                repo,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   154
                remotebranchmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   155
                repo[rtiprev].node(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   156
                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
   157
                closednodes=closed,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   158
            )
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   159
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   160
            # 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
   161
            # 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
   162
            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
   163
                rview = repo.filtered(candidate)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   164
                if cache.validfor(rview):
51489
659f766629c8 branchcache: stop using `copy(…)` in `replace(…)`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51488
diff changeset
   165
                    cache._filtername = candidate
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   166
                    self._per_filter[candidate] = cache
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   167
                    cache._state = STATE_DIRTY
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   168
                    cache.write(rview)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   169
                    return
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   170
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   171
    def clear(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   172
        self._per_filter.clear()
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   173
51488
94f821490645 branchcache: change the _delayed flag to an explicit `_dirty` flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51487
diff changeset
   174
    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
   175
        unfi = repo.unfiltered()
51487
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
   176
        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
   177
            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
   178
            if cache is None:
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
   179
                continue
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   180
            if filtername is None:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   181
                repo = unfi
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   182
            else:
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   183
                repo = unfi.filtered(filtername)
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   184
            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
   185
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   186
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   187
def _unknownnode(node):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   188
    """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
   189
    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
   190
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   191
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   192
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
   193
    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
   194
        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
   195
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   196
        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
   197
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   198
51454
84fca6d79e25 branchcache: introduce a base class for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51453
diff changeset
   199
class _BaseBranchCache:
20181
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   200
    """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
   201
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   202
    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
   203
    branch heads of a repo.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   204
    """
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   205
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   206
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   207
        self,
51287
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   208
        repo: "localrepo.localrepository",
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   209
        entries: Union[
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   210
            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
   211
        ] = (),
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   212
        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
   213
    ) -> None:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   214
        """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
   215
        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
   216
        we have exists in changelog"""
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   217
        # 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
   218
        # 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
   219
        # heads.
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   220
        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
   221
            closed_nodes = set()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   222
        self._closednodes = set(closed_nodes)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   223
        self._entries = dict(entries)
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   224
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   225
    def __iter__(self):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   226
        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
   227
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   228
    def __setitem__(self, key, value):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   229
        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
   230
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   231
    def __getitem__(self, key):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   232
        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
   233
42113
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   234
    def __contains__(self, key):
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   235
        return key in self._entries
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   236
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   237
    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
   238
        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
   239
42603
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
   240
    items = iteritems
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
   241
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   242
    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
   243
        """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
   244
        return label in self._entries
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   245
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   246
    def _branchtip(self, heads):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   247
        """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
   248
        otherwise return last closed head and true."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   249
        tip = heads[-1]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   250
        closed = True
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   251
        for h in reversed(heads):
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   252
            if h not in self._closednodes:
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   253
                tip = h
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   254
                closed = False
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   255
                break
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   256
        return tip, closed
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   257
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   258
    def branchtip(self, branch):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   259
        """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
   260
        tipmost closed head on branch.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   261
        Raise KeyError for unknown branch."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   262
        return self._branchtip(self[branch])[0]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   263
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   264
    def iteropen(self, nodes):
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   265
        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
   266
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   267
    def branchheads(self, branch, closed=False):
42112
29c22496dd97 branchmap: prevent using __getitem__() in branchheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42111
diff changeset
   268
        heads = self._entries[branch]
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   269
        if not closed:
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   270
            heads = list(self.iteropen(heads))
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   271
        return heads
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   272
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   273
    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
   274
        for bn, heads in self.items():
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   275
            yield (bn, heads) + self._branchtip(heads)
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   276
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   277
    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
   278
        """returns all the heads"""
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   279
        return self._entries.values()
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   280
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
   281
    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
   282
        """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
   283
        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
   284
        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
   285
        """
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
   286
        starttime = util.timer()
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   287
        cl = repo.changelog
51532
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   288
        # Faster than using ctx.obsolete()
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   289
        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
   290
        # collect new branch entries
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   291
        newbranches = {}
51534
767b62cb728e branchcache: gather newly closed head in a dedicated set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51533
diff changeset
   292
        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
   293
        obs_ignored = set()
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
   294
        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
   295
        max_rev = -1
18307
0eed2546118a branchmap: Save changectx creation during update
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18305
diff changeset
   296
        for r in revgen:
51532
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   297
            max_rev = max(max_rev, r)
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   298
            if r in obsrevs:
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   299
                # 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
   300
                # considered heads.
51533
50850689d3c0 branchcache: gather new obsolete revision in a set
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51532
diff changeset
   301
                obs_ignored.add(r)
51532
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   302
                continue
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   303
            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
   304
            newbranches.setdefault(branch, []).append(r)
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   305
            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
   306
                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
   307
        if max_rev < 0:
51486
0ddc34330d41 branchcache: do not accept "empty update"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51468
diff changeset
   308
            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
   309
            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
   310
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
   311
        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
   312
            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
   313
            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
   314
            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
   315
            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
   316
            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
   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
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
        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
   320
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
        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
   322
        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
   323
            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
   324
            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
   325
            _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
   326
            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
   327
        )
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
        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
   329
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
    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
   331
        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
   332
        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
   333
        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
   334
        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
   335
        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
   336
        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
   337
    ):
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
   338
        """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
   339
        # 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
   340
        # 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
   341
        topoheads = None
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   342
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
   343
        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
   344
        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
   345
        # 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
   346
        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
   347
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   348
        # 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
   349
        # 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
   350
        parentrevs = cl._uncheckedparentrevs
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   351
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   352
        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
   353
            # 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
   354
            # 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
   355
            # the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   356
            #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   357
            # 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
   358
            # 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
   359
            # 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
   360
            # 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
   361
            #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   362
            # Core observations:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   363
            # - 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
   364
            #   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
   365
            # - 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
   366
            #   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
   367
            #   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
   368
            #   the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   369
            # - 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
   370
            #   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
   371
            #   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
   372
            #   of that parent before.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   373
            # - 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
   374
            #   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
   375
            # - 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
   376
            #   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
   377
            #   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
   378
            #   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
   379
            #   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
   380
            #   a branchhead as ancestor.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   381
            # - 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
   382
            #   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
   383
            #   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
   384
            #   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
   385
            #   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
   386
            #   "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
   387
            #   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
   388
            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
   389
            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
   390
            uncertain = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   391
            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
   392
                if not bheadset:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   393
                    bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   394
                    continue
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   395
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   396
                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
   397
                samebranch = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   398
                otherbranch = set()
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   399
                obsparents = set()
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   400
                for p in parents:
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   401
                    if p in obsrevs:
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   402
                        # 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
   403
                        # 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
   404
                        # 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
   405
                        # 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
   406
                        # changeset as a parent from other branch.
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   407
                        obsparents.add(p)
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   408
                    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
   409
                        samebranch.add(p)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   410
                    else:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   411
                        otherbranch.add(p)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   412
                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
   413
                    uncertain.update(otherbranch)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   414
                    uncertain.update(obsparents)
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   415
                bheadset.difference_update(samebranch)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   416
                bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   417
22357
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   418
            if uncertain:
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   419
                if topoheads is None:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   420
                    topoheads = set(cl.headrevs())
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   421
                if bheadset - topoheads:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   422
                    floorrev = min(bheadset)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   423
                    if floorrev <= max(uncertain):
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   424
                        ancestors = set(cl.ancestors(uncertain, floorrev))
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   425
                        bheadset -= ancestors
48718
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   426
            if bheadset:
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   427
                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
   428
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   429
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   430
STATE_CLEAN = 1
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   431
STATE_INHERITED = 2
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   432
STATE_DIRTY = 3
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   433
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
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
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
   436
    """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
   437
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   438
    _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
   439
    _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
   440
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   441
    def __init__(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   442
        self,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   443
        repo: "localrepo.localrepository",
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   444
        entries: Union[
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   445
            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
   446
        ] = (),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   447
        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
   448
        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
   449
        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
   450
        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
   451
        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
   452
        verify_node: bool = False,
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   453
        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
   454
    ) -> None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   455
        """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
   456
        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
   457
        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
   458
        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
   459
        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
   460
            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
   461
        else:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   462
            self.tipnode = tipnode
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   463
        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
   464
        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
   465
            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
   466
        else:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   467
            self.key_hashes = key_hashes
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   468
        self._state = STATE_CLEAN
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   469
        if inherited:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   470
            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
   471
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   472
        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
   473
        # 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
   474
        # 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
   475
        # heads.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   476
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   477
        # 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
   478
        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
   479
        # 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
   480
        self._verifiedbranches = set()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   481
        self._hasnode = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   482
        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
   483
            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
   484
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   485
    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
   486
        raise NotImplementedError
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   487
51536
718f28ea3af4 branchcache: add a "pure topological head" fast path
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51535
diff changeset
   488
    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
   489
        """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
   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
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   865
    _base_filename = b"branch3"
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
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
  1058
51454
84fca6d79e25 branchcache: introduce a base class for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51453
diff changeset
  1059
class remotebranchcache(_BaseBranchCache):
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
  1060
    """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
  1061
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1062
    def __init__(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1063
        self,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1064
        repo: "localrepo.localrepository",
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1065
        entries: Union[
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1066
            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
  1067
        ] = (),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1068
        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
  1069
    ) -> None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
  1070
        super().__init__(repo=repo, entries=entries, closed_nodes=closednodes)
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
  1071
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
  1072
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1073
# Revision branch info cache
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1074
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1075
_rbcversion = b'-v1'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1076
_rbcnames = b'rbc-names' + _rbcversion
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1077
_rbcrevs = b'rbc-revs' + _rbcversion
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1078
# [4 byte hash prefix][4 byte branch name number with sign bit indicating open]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1079
_rbcrecfmt = b'>4sI'
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1080
_rbcrecsize = calcsize(_rbcrecfmt)
46360
1726a53a8494 reverse-branch-cache: switch to doubling allocating scheme
Joerg Sonnenberger <joerg@bec.de>
parents: 46254
diff changeset
  1081
_rbcmininc = 64 * _rbcrecsize
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1082
_rbcnodelen = 4
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1083
_rbcbranchidxmask = 0x7FFFFFFF
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1084
_rbccloseflag = 0x80000000
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1085
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1086
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1087
class rbcrevs:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1088
    """a byte string consisting of an immutable prefix followed by a mutable suffix"""
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1089
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1090
    def __init__(self, revs):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1091
        self._prefix = revs
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1092
        self._rest = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1093
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1094
    def __len__(self):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1095
        return len(self._prefix) + len(self._rest)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1096
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1097
    def unpack_record(self, rbcrevidx):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1098
        if rbcrevidx < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1099
            return unpack_from(_rbcrecfmt, util.buffer(self._prefix), rbcrevidx)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1100
        else:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1101
            return unpack_from(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1102
                _rbcrecfmt,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1103
                util.buffer(self._rest),
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1104
                rbcrevidx - len(self._prefix),
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1105
            )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1106
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1107
    def make_mutable(self):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1108
        if len(self._prefix) > 0:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1109
            entirety = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1110
            entirety[:] = self._prefix
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1111
            entirety.extend(self._rest)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1112
            self._rest = entirety
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1113
            self._prefix = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1114
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1115
    def truncate(self, pos):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1116
        self.make_mutable()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1117
        del self._rest[pos:]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1118
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1119
    def pack_into(self, rbcrevidx, node, branchidx):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1120
        if rbcrevidx < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1121
            self.make_mutable()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1122
        buf = self._rest
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1123
        start_offset = rbcrevidx - len(self._prefix)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1124
        end_offset = start_offset + _rbcrecsize
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1125
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1126
        if len(self._rest) < end_offset:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1127
            # bytearray doesn't allocate extra space at least in Python 3.7.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1128
            # When multiple changesets are added in a row, precise resize would
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1129
            # result in quadratic complexity. Overallocate to compensate by
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1130
            # using the classic doubling technique for dynamic arrays instead.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1131
            # If there was a gap in the map before, less space will be reserved.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1132
            self._rest.extend(b'\0' * end_offset)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1133
        return pack_into(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1134
            _rbcrecfmt,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1135
            buf,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1136
            start_offset,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1137
            node,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1138
            branchidx,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1139
        )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1140
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1141
    def extend(self, extension):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1142
        return self._rest.extend(extension)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1143
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1144
    def slice(self, begin, end):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1145
        if begin < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1146
            acc = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1147
            acc[:] = self._prefix[begin:end]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1148
            acc.extend(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1149
                self._rest[begin - len(self._prefix) : end - len(self._prefix)]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1150
            )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1151
            return acc
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1152
        return self._rest[begin - len(self._prefix) : end - len(self._prefix)]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1153
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1154
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
  1155
class revbranchcache:
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1156
    """Persistent cache, mapping from revision number to branch name and close.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1157
    This is a low level cache, independent of filtering.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1158
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1159
    Branch names are stored in rbc-names in internal encoding separated by 0.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1160
    rbc-names is append-only, and each branch name is only stored once and will
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1161
    thus have a unique index.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1162
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1163
    The branch info for each revision is stored in rbc-revs as constant size
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1164
    records. The whole file is read into memory, but it is only 'parsed' on
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1165
    demand. The file is usually append-only but will be truncated if repo
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1166
    modification is detected.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1167
    The record for each revision contains the first 4 bytes of the
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1168
    corresponding node hash, and the record is only used if it still matches.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1169
    Even a completely trashed rbc-revs fill thus still give the right result
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1170
    while converging towards full recovery ... assuming no incorrectly matching
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1171
    node hashes.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1172
    The record also contains 4 bytes where 31 bits contains the index of the
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1173
    branch and the last bit indicate that it is a branch close commit.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1174
    The usage pattern for rbc-revs is thus somewhat similar to 00changelog.i
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1175
    and will grow with it but be 1/8th of its size.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1176
    """
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1177
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1178
    def __init__(self, repo, readonly=True):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1179
        assert repo.filtername is None
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
  1180
        self._repo = repo
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1181
        self._names = []  # branch names in local encoding with static index
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1182
        self._rbcrevs = rbcrevs(bytearray())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1183
        self._rbcsnameslen = 0  # length of names read at _rbcsnameslen
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1184
        try:
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
  1185
            bndata = repo.cachevfs.read(_rbcnames)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1186
            self._rbcsnameslen = len(bndata)  # for verification before writing
31371
7dd2f51f38ac rbc: empty (and invalid) rbc-names file should give an empty name list
Mads Kiilerich <mads@kiilerich.com>
parents: 31370
diff changeset
  1187
            if bndata:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1188
                self._names = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1189
                    encoding.tolocal(bn) for bn in bndata.split(b'\0')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1190
                ]
29423
d2c6f3a948fa branchmap: remove unused exception variable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28558
diff changeset
  1191
        except (IOError, OSError):
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1192
            if readonly:
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1193
                # don't try to use cache - fall back to the slow path
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1194
                self.branchinfo = self._branchinfo
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1195
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1196
        if self._names:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1197
            try:
51447
40943970b7ae config: move the option to mmap rev branch cache in the storage section
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
  1198
                if repo.ui.configbool(b'storage', b'revbranchcache.mmap'):
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1199
                    with repo.cachevfs(_rbcrevs) as fp:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1200
                        data = util.buffer(util.mmapread(fp))
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1201
                else:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1202
                    data = repo.cachevfs.read(_rbcrevs)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1203
                self._rbcrevs = rbcrevs(data)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25266
diff changeset
  1204
            except (IOError, OSError) as inst:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1205
                repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1206
                    b"couldn't read revision branch cache: %s\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1207
                    % stringutil.forcebytestr(inst)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1208
                )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1209
        # remember number of good records on disk
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1210
        self._rbcrevslen = min(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1211
            len(self._rbcrevs) // _rbcrecsize, len(repo.changelog)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1212
        )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1213
        if self._rbcrevslen == 0:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1214
            self._names = []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1215
        self._rbcnamescount = len(self._names)  # number of names read at
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1216
        # _rbcsnameslen
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1217
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1218
    def _clear(self):
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1219
        self._rbcsnameslen = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1220
        del self._names[:]
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1221
        self._rbcnamescount = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1222
        self._rbcrevslen = len(self._repo.changelog)
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1223
        self._rbcrevs = rbcrevs(bytearray(self._rbcrevslen * _rbcrecsize))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1224
        util.clearcachedproperty(self, b'_namesreverse')
40710
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
  1225
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
  1226
    @util.propertycache
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
  1227
    def _namesreverse(self):
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44306
diff changeset
  1228
        return {b: r for r, b in enumerate(self._names)}
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1229
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1230
    def branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1231
        """Return branch name and close flag for rev, using and updating
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1232
        persistent cache."""
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1233
        changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1234
        rbcrevidx = rev * _rbcrecsize
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1235
25266
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
  1236
        # avoid negative index, changelog.read(nullrev) is fast without cache
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
  1237
        if rev == nullrev:
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
  1238
            return changelog.branchinfo(rev)
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
  1239
29604
db0095c83344 rbc: fix invalid rbc-revs entries caused by missing cache growth
Mads Kiilerich <madski@unity3d.com>
parents: 29423
diff changeset
  1240
        # if requested rev isn't allocated, grow and cache the rev info
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1241
        if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1242
            return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1243
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1244
        # fast path: extract data from cache, use it if node is matching
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1245
        reponode = changelog.node(rev)[:_rbcnodelen]
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1246
        cachenode, branchidx = self._rbcrevs.unpack_record(rbcrevidx)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1247
        close = bool(branchidx & _rbccloseflag)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1248
        if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1249
            branchidx &= _rbcbranchidxmask
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1250
        if cachenode == b'\0\0\0\0':
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1251
            pass
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1252
        elif cachenode == reponode:
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
  1253
            try:
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1254
                return self._names[branchidx], close
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
  1255
            except IndexError:
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
  1256
                # recover from invalid reference to unknown branch
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1257
                self._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1258
                    b"referenced branch names not found"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1259
                    b" - rebuilding revision branch cache from scratch\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1260
                )
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
  1261
                self._clear()
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1262
        else:
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1263
            # rev/node map has changed, invalidate the cache from here up
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1264
            self._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1265
                b"history modification detected - truncating "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1266
                b"revision branch cache to revision %d\n" % rev
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1267
            )
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1268
            truncate = rbcrevidx + _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1269
            self._rbcrevs.truncate(truncate)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1270
            self._rbcrevslen = min(self._rbcrevslen, truncate)
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1271
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1272
        # fall back to slow path and make sure it will be written to disk
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1273
        return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1274
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1275
    def _branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1276
        """Retrieve branch info from changelog and update _rbcrevs"""
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1277
        changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1278
        b, close = changelog.branchinfo(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1279
        if b in self._namesreverse:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1280
            branchidx = self._namesreverse[b]
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1281
        else:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1282
            branchidx = len(self._names)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1283
            self._names.append(b)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1284
            self._namesreverse[b] = branchidx
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1285
        reponode = changelog.node(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1286
        if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1287
            branchidx |= _rbccloseflag
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1288
        self._setcachedata(rev, reponode, branchidx)
24375
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
  1289
        return b, close
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
  1290
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
  1291
    def setdata(self, rev, changelogrevision):
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1292
        """add new data information to the cache"""
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
  1293
        branch, close = changelogrevision.branchinfo
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
  1294
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1295
        if branch in self._namesreverse:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1296
            branchidx = self._namesreverse[branch]
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1297
        else:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1298
            branchidx = len(self._names)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1299
            self._names.append(branch)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1300
            self._namesreverse[branch] = branchidx
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1301
        if close:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1302
            branchidx |= _rbccloseflag
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
  1303
        self._setcachedata(rev, self._repo.changelog.node(rev), branchidx)
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1304
        # If no cache data were readable (non exists, bad permission, etc)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1305
        # the cache was bypassing itself by setting:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1306
        #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1307
        #   self.branchinfo = self._branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1308
        #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1309
        # Since we now have data in the cache, we need to drop this bypassing.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43499
diff changeset
  1310
        if 'branchinfo' in vars(self):
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1311
            del self.branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1312
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1313
    def _setcachedata(self, rev, node, branchidx):
24375
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
  1314
        """Writes the node's branch data to the in-memory cache data."""
31454
a5bad127128d branchmap: handle nullrev in setcachedata
Durham Goode <durham@fb.com>
parents: 31381
diff changeset
  1315
        if rev == nullrev:
a5bad127128d branchmap: handle nullrev in setcachedata
Durham Goode <durham@fb.com>
parents: 31381
diff changeset
  1316
            return
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1317
        rbcrevidx = rev * _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1318
        self._rbcrevs.pack_into(rbcrevidx, node, branchidx)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1319
        self._rbcrevslen = min(self._rbcrevslen, rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1320
24377
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
  1321
        tr = self._repo.currenttransaction()
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
  1322
        if tr:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1323
            tr.addfinalize(b'write-revbranchcache', self.write)
24377
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
  1324
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
  1325
    def write(self, tr=None):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1326
        """Save branch cache if it is dirty."""
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
  1327
        repo = self._repo
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1328
        wlock = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1329
        step = b''
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1330
        try:
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1331
            # write the new names
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
  1332
            if self._rbcnamescount < len(self._names):
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1333
                wlock = repo.wlock(wait=False)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1334
                step = b' names'
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1335
                self._writenames(repo)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1336
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1337
            # write the new revs
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
  1338
            start = self._rbcrevslen * _rbcrecsize
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
  1339
            if start != len(self._rbcrevs):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1340
                step = b''
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1341
                if wlock is None:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1342
                    wlock = repo.wlock(wait=False)
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1343
                self._writerevs(repo, start)
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1344
29745
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
  1345
        except (IOError, OSError, error.Abort, error.LockError) as inst:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1346
            repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1347
                b"couldn't write revision branch cache%s: %s\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1348
                % (step, stringutil.forcebytestr(inst))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1349
            )
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1350
        finally:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1351
            if wlock is not None:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1352
                wlock.release()
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1353
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1354
    def _writenames(self, repo):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
  1355
        """write the new branch names to revbranchcache"""
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1356
        if self._rbcnamescount != 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1357
            f = repo.cachevfs.open(_rbcnames, b'ab')
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1358
            if f.tell() == self._rbcsnameslen:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1359
                f.write(b'\0')
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1360
            else:
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1361
                f.close()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1362
                repo.ui.debug(b"%s changed - rewriting it\n" % _rbcnames)
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1363
                self._rbcnamescount = 0
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1364
                self._rbcrevslen = 0
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1365
        if self._rbcnamescount == 0:
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1366
            # before rewriting names, make sure references are removed
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1367
            repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1368
            f = repo.cachevfs.open(_rbcnames, b'wb')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1369
        f.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1370
            b'\0'.join(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1371
                encoding.fromlocal(b)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1372
                for b in self._names[self._rbcnamescount :]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1373
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1374
        )
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1375
        self._rbcsnameslen = f.tell()
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1376
        f.close()
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1377
        self._rbcnamescount = len(self._names)
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1378
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1379
    def _writerevs(self, repo, start):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
  1380
        """write the new revs to revbranchcache"""
42185
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1381
        revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1382
        with repo.cachevfs.open(_rbcrevs, b'ab') as f:
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1383
            if f.tell() != start:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1384
                repo.ui.debug(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1385
                    b"truncating cache/%s to %d\n" % (_rbcrevs, start)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1386
                )
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1387
                f.seek(start)
42185
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1388
                if f.tell() != start:
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1389
                    start = 0
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1390
                    f.seek(start)
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1391
                f.truncate()
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1392
            end = revs * _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1393
            f.write(self._rbcrevs.slice(start, end))
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1394
        self._rbcrevslen = revs