mercurial/branchmap.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Wed, 06 Mar 2024 15:54:22 +0100
changeset 51532 a0ef462cf1a4
parent 51531 f85f23f1479b
child 51533 50850689d3c0
permissions -rw-r--r--
branchcache: filter obsolete revisions sooner Since we won't do anything with the obsolete revisions, we can just ignore them sooner.
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]
51451
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
    65
        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
    66
            bcache._filtername,
51450
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    67
            repo.filtername,
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    68
        )
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
    69
        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
    70
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
    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
    72
        """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
    73
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
        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
    75
        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
    76
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
        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
    78
        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
    79
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
        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
    81
        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
    82
        """
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
        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
    84
        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
    85
        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
    86
            bcache._filtername,
51450
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    87
            repo.filtername,
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
    88
        )
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
    89
        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
    90
        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
    91
            bcache.sync_disk(repo)
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    92
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    93
    def updatecache(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    94
        """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
    95
        # 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
    96
        # 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
    97
        # is stale.
18121
f8a13f061a8a branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18120
diff changeset
    98
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    99
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   100
        filtername = repo.filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   101
        bcache = self._per_filter.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   102
        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
   103
            # 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
   104
            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
   105
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   106
        revs = []
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   107
        if bcache is None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   108
            # 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
   109
            # 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
   110
            # revisions.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   111
            subsetname = subsettable.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   112
            if subsetname is not None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   113
                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
   114
                self.updatecache(subset)
54f0dd798346 branchcache: do not use `__getitem__` in updatecache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51493
diff changeset
   115
                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
   116
                extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   117
                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
   118
            else:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   119
                # 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
   120
                bcache = new_branch_cache(repo)
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
   121
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   122
        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
   123
        if revs:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   124
            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
   125
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   126
        assert bcache.validfor(repo), filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   127
        self._per_filter[repo.filtername] = bcache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   128
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   129
    def replace(self, repo, remotebranchmap):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   130
        """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
   131
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   132
        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
   133
        remote.
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   134
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   135
        """
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   136
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   137
        clrev = cl.rev
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   138
        clbranchinfo = cl.branchinfo
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   139
        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
   140
        closed = set()
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   141
        for bheads in remotebranchmap.values():
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   142
            rbheads += bheads
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   143
            for h in bheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   144
                r = clrev(h)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   145
                b, c = clbranchinfo(r)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   146
                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
   147
                    closed.add(h)
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   148
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   149
        if rbheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   150
            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
   151
            cache = new_branch_cache(
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
   152
                repo,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   153
                remotebranchmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   154
                repo[rtiprev].node(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   155
                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
   156
                closednodes=closed,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   157
            )
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   158
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   159
            # 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
   160
            # 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
   161
            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
   162
                rview = repo.filtered(candidate)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   163
                if cache.validfor(rview):
51489
659f766629c8 branchcache: stop using `copy(…)` in `replace(…)`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51488
diff changeset
   164
                    cache._filtername = candidate
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   165
                    self._per_filter[candidate] = cache
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   166
                    cache._state = STATE_DIRTY
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   167
                    cache.write(rview)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   168
                    return
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   169
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   170
    def clear(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   171
        self._per_filter.clear()
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   172
51488
94f821490645 branchcache: change the _delayed flag to an explicit `_dirty` flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51487
diff changeset
   173
    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
   174
        unfi = repo.unfiltered()
51487
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
   175
        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
   176
            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
   177
            if cache is None:
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
   178
                continue
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   179
            if filtername is None:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   180
                repo = unfi
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   181
            else:
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   182
                repo = unfi.filtered(filtername)
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   183
            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
   184
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   185
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   186
def _unknownnode(node):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   187
    """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
   188
    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
   189
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   190
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   191
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
   192
    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
   193
        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
   194
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   195
        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
   196
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   197
51454
84fca6d79e25 branchcache: introduce a base class for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51453
diff changeset
   198
class _BaseBranchCache:
20181
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   199
    """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
   200
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   201
    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
   202
    branch heads of a repo.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   203
    """
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   204
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   205
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   206
        self,
51287
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   207
        repo: "localrepo.localrepository",
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   208
        entries: Union[
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   209
            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
   210
        ] = (),
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   211
        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
   212
    ) -> None:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   213
        """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
   214
        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
   215
        we have exists in changelog"""
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   216
        # 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
   217
        # 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
   218
        # heads.
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   219
        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
   220
            closed_nodes = set()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   221
        self._closednodes = set(closed_nodes)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   222
        self._entries = dict(entries)
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   223
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   224
    def __iter__(self):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   225
        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
   226
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   227
    def __setitem__(self, key, value):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   228
        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
   229
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   230
    def __getitem__(self, key):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   231
        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
   232
42113
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   233
    def __contains__(self, key):
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   234
        return key in self._entries
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   235
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   236
    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
   237
        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
   238
42603
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
   239
    items = iteritems
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
   240
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   241
    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
   242
        """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
   243
        return label in self._entries
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   244
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   245
    def _branchtip(self, heads):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   246
        """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
   247
        otherwise return last closed head and true."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   248
        tip = heads[-1]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   249
        closed = True
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   250
        for h in reversed(heads):
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   251
            if h not in self._closednodes:
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   252
                tip = h
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   253
                closed = False
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   254
                break
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   255
        return tip, closed
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   256
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   257
    def branchtip(self, branch):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   258
        """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
   259
        tipmost closed head on branch.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   260
        Raise KeyError for unknown branch."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   261
        return self._branchtip(self[branch])[0]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   262
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   263
    def iteropen(self, nodes):
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   264
        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
   265
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   266
    def branchheads(self, branch, closed=False):
42112
29c22496dd97 branchmap: prevent using __getitem__() in branchheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42111
diff changeset
   267
        heads = self._entries[branch]
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   268
        if not closed:
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   269
            heads = list(self.iteropen(heads))
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   270
        return heads
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   271
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   272
    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
   273
        for bn, heads in self.items():
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   274
            yield (bn, heads) + self._branchtip(heads)
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   275
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   276
    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
   277
        """returns all the heads"""
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   278
        return self._entries.values()
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   279
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
   280
    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
   281
        """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
   282
        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
   283
        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
   284
        """
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
   285
        starttime = util.timer()
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   286
        cl = repo.changelog
51532
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   287
        # Faster than using ctx.obsolete()
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   288
        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
   289
        # collect new branch entries
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   290
        newbranches = {}
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
   291
        getbranchinfo = repo.revbranchcache().branchinfo
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   292
        max_rev = -1
18307
0eed2546118a branchmap: Save changectx creation during update
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18305
diff changeset
   293
        for r in revgen:
51532
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   294
            max_rev = max(max_rev, r)
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   295
            if r in obsrevs:
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   296
                # We ignore obsolete changesets as they shouldn't be
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   297
                # considered heads.
a0ef462cf1a4 branchcache: filter obsolete revisions sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51531
diff changeset
   298
                continue
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   299
            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
   300
            newbranches.setdefault(branch, []).append(r)
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   301
            if closesbranch:
20262
cf450ee3f8f7 branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20261
diff changeset
   302
                self._closednodes.add(cl.node(r))
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   303
        if max_rev < 0:
51486
0ddc34330d41 branchcache: do not accept "empty update"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51468
diff changeset
   304
            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
   305
            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
   306
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   307
        # 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
   308
        # 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
   309
        topoheads = None
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   310
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   311
        # 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
   312
        # use the faster unfiltered parent accessor.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   313
        parentrevs = repo.unfiltered().changelog.parentrevs
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   314
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   315
        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
   316
            # 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
   317
            # 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
   318
            # the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   319
            #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   320
            # 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
   321
            # 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
   322
            # 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
   323
            # 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
   324
            #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   325
            # Core observations:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   326
            # - 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
   327
            #   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
   328
            # - 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
   329
            #   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
   330
            #   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
   331
            #   the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   332
            # - 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
   333
            #   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
   334
            #   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
   335
            #   of that parent before.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   336
            # - 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
   337
            #   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
   338
            # - 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
   339
            #   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
   340
            #   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
   341
            #   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
   342
            #   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
   343
            #   a branchhead as ancestor.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   344
            # - 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
   345
            #   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
   346
            #   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
   347
            #   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
   348
            #   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
   349
            #   "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
   350
            #   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
   351
            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
   352
            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
   353
            uncertain = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   354
            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
   355
                if not bheadset:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   356
                    bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   357
                    continue
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   358
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   359
                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
   360
                samebranch = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   361
                otherbranch = set()
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   362
                obsparents = set()
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   363
                for p in parents:
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   364
                    if p in obsrevs:
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   365
                        # 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
   366
                        # 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
   367
                        # 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
   368
                        # 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
   369
                        # changeset as a parent from other branch.
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   370
                        obsparents.add(p)
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   371
                    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
   372
                        samebranch.add(p)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   373
                    else:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   374
                        otherbranch.add(p)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   375
                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
   376
                    uncertain.update(otherbranch)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   377
                    uncertain.update(obsparents)
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   378
                bheadset.difference_update(samebranch)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   379
                bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   380
22357
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   381
            if uncertain:
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   382
                if topoheads is None:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   383
                    topoheads = set(cl.headrevs())
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   384
                if bheadset - topoheads:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   385
                    floorrev = min(bheadset)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   386
                    if floorrev <= max(uncertain):
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   387
                        ancestors = set(cl.ancestors(uncertain, floorrev))
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   388
                        bheadset -= ancestors
48718
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   389
            if bheadset:
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   390
                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
   391
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   392
        duration = util.timer() - starttime
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   393
        repo.ui.log(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   394
            b'branchcache',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   395
            b'updated %s in %.4f seconds\n',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   396
            _branchcachedesc(repo),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   397
            duration,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   398
        )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   399
        return max_rev
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   400
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   401
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   402
STATE_CLEAN = 1
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   403
STATE_INHERITED = 2
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   404
STATE_DIRTY = 3
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   405
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   406
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   407
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
   408
    """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
   409
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   410
    _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
   411
    _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
   412
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   413
    def __init__(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   414
        self,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   415
        repo: "localrepo.localrepository",
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   416
        entries: Union[
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   417
            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
   418
        ] = (),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   419
        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
   420
        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
   421
        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
   422
        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
   423
        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
   424
        verify_node: bool = False,
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   425
        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
   426
    ) -> None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   427
        """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
   428
        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
   429
        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
   430
        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
   431
        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
   432
            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
   433
        else:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   434
            self.tipnode = tipnode
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   435
        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
   436
        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
   437
            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
   438
        else:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   439
            self.key_hashes = key_hashes
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   440
        self._state = STATE_CLEAN
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   441
        if inherited:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   442
            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
   443
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   444
        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
   445
        # 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
   446
        # 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
   447
        # heads.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   448
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   449
        # 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
   450
        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
   451
        # 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
   452
        self._verifiedbranches = set()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   453
        self._hasnode = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   454
        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
   455
            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
   456
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   457
    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
   458
        raise NotImplementedError
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   459
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   460
    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
   461
        """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
   462
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   463
        - 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
   464
        - 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
   465
        try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   466
            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
   467
        except IndexError:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   468
            # 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
   469
            # find tiprev
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   470
            return False
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   471
        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
   472
            # 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
   473
            # 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
   474
            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
   475
        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
   476
        # 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
   477
        # 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
   478
        # 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
   479
        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
   480
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   481
    @classmethod
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   482
    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
   483
        f = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   484
        try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   485
            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
   486
            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
   487
            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
   488
            bcache = cls(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   489
                repo,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   490
                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
   491
                **init_kwargs,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   492
            )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   493
            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
   494
                # invalidate the cache
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   495
                raise ValueError('tip differs')
51461
47752632b4fc branchcache: rename `load` to `_load_heads`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51460
diff changeset
   496
            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
   497
        except (IOError, OSError):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   498
            return None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   499
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   500
        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
   501
            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
   502
                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
   503
                msg %= (
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
   504
                    _branchcachedesc(repo),
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
   505
                    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
   506
                )
51462
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
   507
                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
   508
            bcache = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   509
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   510
        finally:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   511
            if f:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   512
                f.close()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   513
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   514
        return bcache
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   515
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
   516
    @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
   517
    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
   518
        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
   519
51461
47752632b4fc branchcache: rename `load` to `_load_heads`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51460
diff changeset
   520
    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
   521
        """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
   522
        iterator passed"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   523
        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
   524
            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
   525
            if not line:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   526
                continue
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   527
            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
   528
            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
   529
                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
   530
            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
   531
            node = bin(node)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   532
            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
   533
            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
   534
                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
   535
51460
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
   536
    @classmethod
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
   537
    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
   538
        """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
   539
        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
   540
        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
   541
        if repo.filtername:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   542
            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
   543
        return filename
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   544
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   545
    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
   546
        """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
   547
        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
   548
        other = type(self)(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   549
            repo=repo,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   550
            # 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
   551
            # 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
   552
            # true.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   553
            entries=self._entries,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   554
            tipnode=self.tipnode,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   555
            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
   556
            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
   557
            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
   558
            verify_node=self._verify_node,
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   559
            inherited=True,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   560
        )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   561
        # 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
   562
        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
   563
        return other
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   564
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   565
    def sync_disk(self, repo):
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   566
        """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
   567
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   568
        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
   569
        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
   570
        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
   571
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   572
        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
   573
        """
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   574
        if self._state == STATE_DIRTY:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   575
            self.write(repo)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   576
        elif self._state == STATE_INHERITED:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   577
            filename = self._filename(repo)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   578
            repo.cachevfs.tryunlink(filename)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   579
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   580
    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
   581
        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
   582
            self._filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   583
            repo.filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   584
        )
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   585
        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
   586
        # 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
   587
        tr = repo.currenttransaction()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   588
        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
   589
            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
   590
            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
   591
        try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   592
            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
   593
            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
   594
                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
   595
                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
   596
            repo.ui.log(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   597
                b'branchcache',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   598
                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
   599
                _branchcachedesc(repo),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   600
                len(self._entries),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   601
                nodecount,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   602
            )
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   603
            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
   604
        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
   605
            # 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
   606
            repo.ui.debug(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   607
                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
   608
                % stringutil.forcebytestr(inst)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   609
            )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   610
51465
9007387a227c branchcache: move head writing in a `_write_headers` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51464
diff changeset
   611
    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
   612
        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
   613
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
   614
    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
   615
        """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
   616
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   617
        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
   618
        nodecount = 0
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   619
        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
   620
            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
   621
            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
   622
                nodecount += 1
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   623
                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
   624
                    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
   625
                else:
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   626
                    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
   627
                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
   628
        return nodecount
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
   629
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   630
    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
   631
        """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
   632
        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
   633
            return
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   634
        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
   635
            return
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   636
        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
   637
        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
   638
            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
   639
                _unknownnode(n)
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
        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
   642
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   643
    def _verifyall(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   644
        """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
   645
        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
   646
            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
   647
                self._verifybranch(b)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   648
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   649
    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
   650
        self._verifybranch(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   651
        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
   652
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   653
    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
   654
        self._verifybranch(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   655
        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
   656
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   657
    def iteritems(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   658
        self._verifyall()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   659
        return super().iteritems()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   660
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   661
    items = iteritems
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   662
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   663
    def iterheads(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   664
        """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
   665
        self._verifyall()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   666
        return super().iterheads()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   667
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   668
    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
   669
        """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
   670
        self._verifybranch(label)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   671
        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
   672
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   673
    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
   674
        self._verifybranch(branch)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   675
        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
   676
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   677
    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
   678
        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
   679
            self._filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   680
            repo.filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   681
        )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   682
        cl = repo.changelog
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   683
        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
   684
        # 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
   685
        # branches
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   686
        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
   687
            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
   688
            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
   689
        else:
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   690
            # 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
   691
            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
   692
19838
23386881abeb branchmap: remove the droppednodes logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19837
diff changeset
   693
        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
   694
            # 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
   695
            # 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
   696
            # 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
   697
            #
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   698
            # 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
   699
            # 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
   700
            # 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
   701
            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
   702
            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
   703
                repo,
a03fa40afd01 filteredhash: rename the filteredhash function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51523
diff changeset
   704
                self.tiprev,
51523
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   705
            )
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
   706
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
   707
        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
   708
        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
   709
        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
   710
            # 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
   711
            #
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
   712
            # (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
   713
            self.write(repo)
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   714
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   715
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   716
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
   717
    """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
   718
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   719
    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
   720
    """
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   721
    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
   722
        return BranchCacheV3.fromfile(repo)
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   723
    else:
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   724
        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
   725
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   726
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   727
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
   728
    """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
   729
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   730
    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
   731
    """
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   732
    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
   733
        return BranchCacheV3(repo, *args, **kwargs)
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   734
    else:
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   735
        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
   736
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   737
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   738
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
   739
    """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
   740
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   741
    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
   742
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   743
    <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
   744
    <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
   745
    <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
   746
    ...
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   747
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   748
    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
   749
    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
   750
    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
   751
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   752
    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
   753
    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
   754
    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
   755
    """
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
    _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
   758
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   759
    @classmethod
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   760
    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
   761
        """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
   762
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   763
        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
   764
        """
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   765
        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
   766
        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
   767
        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
   768
        filteredhash = ()
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   769
        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
   770
            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
   771
        return {
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   772
            "tipnode": last,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   773
            "tiprev": lrev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   774
            "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
   775
        }
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   776
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   777
    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
   778
        """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
   779
        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
   780
        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
   781
            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
   782
        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
   783
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   784
    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
   785
        """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
   786
        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
   787
            repo,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   788
            self.tiprev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   789
            needobsolete=True,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   790
        )
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   791
        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
   792
        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
   793
            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
   794
        return keys
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   795
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
   796
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   797
class BranchCacheV3(_LocalBranchCache):
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   798
    """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
   799
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   800
    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
   801
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   802
    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
   803
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   804
    <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
   805
    <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
   806
    <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
   807
    ...
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   808
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   809
    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
   810
    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
   811
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   812
    - 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
   813
    - 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
   814
    - 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
   815
                     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
   816
    - 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
   817
                     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
   818
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   819
    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
   820
    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
   821
51529
4141d12de073 branchcache: store filtered hash and obsolete hash independently for V3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51527
diff changeset
   822
    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
   823
    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
   824
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   825
    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
   826
    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
   827
    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
   828
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
   829
    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
   830
    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
   831
    ignored.
51520
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
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   834
    _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
   835
    _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
   836
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
   837
    def _get_topo_heads(self, repo) -> List[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
   838
        """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
   839
        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
   840
        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
   841
            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
   842
        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
   843
            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
   844
        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
   845
            # 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
   846
            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
   847
            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
   848
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   849
    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
   850
        cache_keys = {
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   851
            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
   852
            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
   853
        }
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   854
        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
   855
            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
   856
                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
   857
            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
   858
                cache_keys[b"obsolete-hash"] = hex(self.key_hashes[1])
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   859
        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
   860
        fp.write(b" ".join(pieces) + b'\n')
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   861
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
   862
    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
   863
        """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
   864
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
   865
        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
   866
        nodecount = 0
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
   867
        topo_heads = set(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
   868
        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
   869
        for label, nodes in sorted(self._entries.items()):
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
   870
            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
   871
            for node in nodes:
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
   872
                rev = to_rev(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
   873
                if rev in topo_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
   874
                    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
   875
                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
   876
                    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
   877
                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
   878
                    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
   879
                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
   880
                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
   881
        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
   882
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   883
    @classmethod
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   884
    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
   885
        header_line = next(lineiter)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   886
        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
   887
        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
   888
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   889
        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
   890
        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
   891
        obsolete_hash = None
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   892
        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
   893
            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
   894
                args["tiprev"] = int(v)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   895
            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
   896
                args["tipnode"] = bin(v)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   897
            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
   898
                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
   899
            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
   900
                obsolete_hash = bin(v)
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   901
            else:
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   902
                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
   903
                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
   904
        args["key_hashes"] = (filtered_hash, obsolete_hash)
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   905
        return args
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
   906
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
   907
    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
   908
        """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
   909
        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
   910
        super()._load_heads(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
   911
        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
   912
        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
   913
        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
   914
        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
   915
        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
   916
        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
   917
            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
   918
                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
   919
            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
   920
            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
   921
            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
   922
            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
   923
                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
   924
            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
   925
        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
   926
        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
   927
            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
   928
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   929
    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
   930
        """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
   931
        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
   932
            repo,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   933
            self.tiprev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   934
        )
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
   935
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
   936
51454
84fca6d79e25 branchcache: introduce a base class for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51453
diff changeset
   937
class remotebranchcache(_BaseBranchCache):
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   938
    """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
   939
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   940
    def __init__(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   941
        self,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   942
        repo: "localrepo.localrepository",
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   943
        entries: Union[
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   944
            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
   945
        ] = (),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   946
        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
   947
    ) -> None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
   948
        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
   949
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   950
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   951
# Revision branch info cache
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   952
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   953
_rbcversion = b'-v1'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   954
_rbcnames = b'rbc-names' + _rbcversion
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   955
_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
   956
# [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
   957
_rbcrecfmt = b'>4sI'
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   958
_rbcrecsize = calcsize(_rbcrecfmt)
46360
1726a53a8494 reverse-branch-cache: switch to doubling allocating scheme
Joerg Sonnenberger <joerg@bec.de>
parents: 46254
diff changeset
   959
_rbcmininc = 64 * _rbcrecsize
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   960
_rbcnodelen = 4
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   961
_rbcbranchidxmask = 0x7FFFFFFF
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   962
_rbccloseflag = 0x80000000
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   963
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   964
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   965
class rbcrevs:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   966
    """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
   967
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   968
    def __init__(self, revs):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   969
        self._prefix = revs
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   970
        self._rest = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   971
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   972
    def __len__(self):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   973
        return len(self._prefix) + len(self._rest)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   974
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   975
    def unpack_record(self, rbcrevidx):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   976
        if rbcrevidx < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   977
            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
   978
        else:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   979
            return unpack_from(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   980
                _rbcrecfmt,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   981
                util.buffer(self._rest),
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   982
                rbcrevidx - len(self._prefix),
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   983
            )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   984
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   985
    def make_mutable(self):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   986
        if len(self._prefix) > 0:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   987
            entirety = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   988
            entirety[:] = self._prefix
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   989
            entirety.extend(self._rest)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   990
            self._rest = entirety
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   991
            self._prefix = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   992
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   993
    def truncate(self, pos):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   994
        self.make_mutable()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   995
        del self._rest[pos:]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   996
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   997
    def pack_into(self, rbcrevidx, node, branchidx):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   998
        if rbcrevidx < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   999
            self.make_mutable()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1000
        buf = self._rest
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1001
        start_offset = rbcrevidx - len(self._prefix)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1002
        end_offset = start_offset + _rbcrecsize
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1003
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1004
        if len(self._rest) < end_offset:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1005
            # 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
  1006
            # 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
  1007
            # 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
  1008
            # 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
  1009
            # 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
  1010
            self._rest.extend(b'\0' * end_offset)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1011
        return pack_into(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1012
            _rbcrecfmt,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1013
            buf,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1014
            start_offset,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1015
            node,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1016
            branchidx,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1017
        )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1018
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1019
    def extend(self, extension):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1020
        return self._rest.extend(extension)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1021
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1022
    def slice(self, begin, end):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1023
        if begin < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1024
            acc = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1025
            acc[:] = self._prefix[begin:end]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1026
            acc.extend(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1027
                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
  1028
            )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1029
            return acc
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1030
        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
  1031
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1032
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
  1033
class revbranchcache:
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1034
    """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
  1035
    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
  1036
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1037
    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
  1038
    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
  1039
    thus have a unique index.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1040
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1041
    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
  1042
    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
  1043
    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
  1044
    modification is detected.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1045
    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
  1046
    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
  1047
    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
  1048
    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
  1049
    node hashes.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1050
    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
  1051
    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
  1052
    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
  1053
    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
  1054
    """
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1055
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1056
    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
  1057
        assert repo.filtername is None
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
  1058
        self._repo = repo
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1059
        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
  1060
        self._rbcrevs = rbcrevs(bytearray())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1061
        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
  1062
        try:
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
  1063
            bndata = repo.cachevfs.read(_rbcnames)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1064
            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
  1065
            if bndata:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1066
                self._names = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1067
                    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
  1068
                ]
29423
d2c6f3a948fa branchmap: remove unused exception variable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28558
diff changeset
  1069
        except (IOError, OSError):
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1070
            if readonly:
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1071
                # 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
  1072
                self.branchinfo = self._branchinfo
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
  1073
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1074
        if self._names:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1075
            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
  1076
                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
  1077
                    with repo.cachevfs(_rbcrevs) as fp:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1078
                        data = util.buffer(util.mmapread(fp))
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1079
                else:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1080
                    data = repo.cachevfs.read(_rbcrevs)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1081
                self._rbcrevs = rbcrevs(data)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25266
diff changeset
  1082
            except (IOError, OSError) as inst:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1083
                repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1084
                    b"couldn't read revision branch cache: %s\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1085
                    % stringutil.forcebytestr(inst)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1086
                )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1087
        # remember number of good records on disk
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1088
        self._rbcrevslen = min(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1089
            len(self._rbcrevs) // _rbcrecsize, len(repo.changelog)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1090
        )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1091
        if self._rbcrevslen == 0:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1092
            self._names = []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1093
        self._rbcnamescount = len(self._names)  # number of names read at
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1094
        # _rbcsnameslen
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1095
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1096
    def _clear(self):
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1097
        self._rbcsnameslen = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1098
        del self._names[:]
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1099
        self._rbcnamescount = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1100
        self._rbcrevslen = len(self._repo.changelog)
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1101
        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
  1102
        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
  1103
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
  1104
    @util.propertycache
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
  1105
    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
  1106
        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
  1107
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1108
    def branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1109
        """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
  1110
        persistent cache."""
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1111
        changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1112
        rbcrevidx = rev * _rbcrecsize
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1113
25266
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
  1114
        # 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
  1115
        if rev == nullrev:
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
  1116
            return changelog.branchinfo(rev)
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
  1117
29604
db0095c83344 rbc: fix invalid rbc-revs entries caused by missing cache growth
Mads Kiilerich <madski@unity3d.com>
parents: 29423
diff changeset
  1118
        # 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
  1119
        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
  1120
            return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1121
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1122
        # 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
  1123
        reponode = changelog.node(rev)[:_rbcnodelen]
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1124
        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
  1125
        close = bool(branchidx & _rbccloseflag)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1126
        if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1127
            branchidx &= _rbcbranchidxmask
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1128
        if cachenode == b'\0\0\0\0':
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1129
            pass
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1130
        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
  1131
            try:
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
  1132
                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
  1133
            except IndexError:
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
  1134
                # recover from invalid reference to unknown branch
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1135
                self._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1136
                    b"referenced branch names not found"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1137
                    b" - rebuilding revision branch cache from scratch\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1138
                )
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
  1139
                self._clear()
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1140
        else:
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1141
            # 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
  1142
            self._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1143
                b"history modification detected - truncating "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1144
                b"revision branch cache to revision %d\n" % rev
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1145
            )
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1146
            truncate = rbcrevidx + _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1147
            self._rbcrevs.truncate(truncate)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1148
            self._rbcrevslen = min(self._rbcrevslen, truncate)
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1149
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1150
        # 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
  1151
        return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1152
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1153
    def _branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1154
        """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
  1155
        changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1156
        b, close = changelog.branchinfo(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1157
        if b in self._namesreverse:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1158
            branchidx = self._namesreverse[b]
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1159
        else:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1160
            branchidx = len(self._names)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1161
            self._names.append(b)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1162
            self._namesreverse[b] = branchidx
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1163
        reponode = changelog.node(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1164
        if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1165
            branchidx |= _rbccloseflag
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1166
        self._setcachedata(rev, reponode, branchidx)
24375
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
  1167
        return b, close
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
  1168
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
  1169
    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
  1170
        """add new data information to the cache"""
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
  1171
        branch, close = changelogrevision.branchinfo
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
  1172
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1173
        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
  1174
            branchidx = self._namesreverse[branch]
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1175
        else:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1176
            branchidx = len(self._names)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1177
            self._names.append(branch)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1178
            self._namesreverse[branch] = branchidx
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1179
        if close:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1180
            branchidx |= _rbccloseflag
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
  1181
        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
  1182
        # 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
  1183
        # 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
  1184
        #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1185
        #   self.branchinfo = self._branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1186
        #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1187
        # 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
  1188
        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
  1189
            del self.branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
  1190
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
  1191
    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
  1192
        """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
  1193
        if rev == nullrev:
a5bad127128d branchmap: handle nullrev in setcachedata
Durham Goode <durham@fb.com>
parents: 31381
diff changeset
  1194
            return
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1195
        rbcrevidx = rev * _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1196
        self._rbcrevs.pack_into(rbcrevidx, node, branchidx)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
  1197
        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
  1198
24377
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
  1199
        tr = self._repo.currenttransaction()
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
  1200
        if tr:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1201
            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
  1202
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
  1203
    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
  1204
        """Save branch cache if it is dirty."""
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
  1205
        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
  1206
        wlock = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1207
        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
  1208
        try:
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1209
            # 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
  1210
            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
  1211
                wlock = repo.wlock(wait=False)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1212
                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
  1213
                self._writenames(repo)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
  1214
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1215
            # 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
  1216
            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
  1217
            if start != len(self._rbcrevs):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1218
                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
  1219
                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
  1220
                    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
  1221
                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
  1222
29745
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
  1223
        except (IOError, OSError, error.Abort, error.LockError) as inst:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1224
            repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1225
                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
  1226
                % (step, stringutil.forcebytestr(inst))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1227
            )
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1228
        finally:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
  1229
            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
  1230
                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
  1231
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1232
    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
  1233
        """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
  1234
        if self._rbcnamescount != 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1235
            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
  1236
            if f.tell() == self._rbcsnameslen:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1237
                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
  1238
            else:
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1239
                f.close()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1240
                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
  1241
                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
  1242
                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
  1243
        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
  1244
            # 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
  1245
            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
  1246
            f = repo.cachevfs.open(_rbcnames, b'wb')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1247
        f.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1248
            b'\0'.join(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1249
                encoding.fromlocal(b)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1250
                for b in self._names[self._rbcnamescount :]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1251
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
  1252
        )
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1253
        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
  1254
        f.close()
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1255
        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
  1256
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1257
    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
  1258
        """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
  1259
        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
  1260
        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
  1261
            if f.tell() != start:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1262
                repo.ui.debug(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1263
                    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
  1264
                )
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
  1265
                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
  1266
                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
  1267
                    start = 0
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1268
                    f.seek(start)
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1269
                f.truncate()
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
  1270
            end = revs * _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
  1271
            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
  1272
        self._rbcrevslen = revs