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