hgext3rd/evolve/obscache.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 11 May 2017 16:58:43 +0200
changeset 2346 34c6382dbb82
parent 2345 406c1a57b4ee
child 2347 24bf0e3d84e3
permissions -rw-r--r--
obscache: guard from changing changelog or obsstore object We access these object once to make sure they will never change through the function (and their content will be fixed).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     1
# Code dedicated to an cache around obsolescence property
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     2
#
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     3
# This module content aims at being upstreamed.
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     4
#
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     5
# Copyright 2017 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     6
#
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     7
# This software may be used and distributed according to the terms of the
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     8
# GNU General Public License version 2 or any later version.
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     9
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    10
import hashlib
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    11
import struct
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    12
import weakref
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    13
import errno
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    14
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    15
from mercurial import (
2328
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
    16
    error,
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    17
    localrepo,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    18
    obsolete,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    19
    phases,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    20
    node,
2315
e16f6bef5848 compat: make obscache code compatible with Mercurial version prior to 4.2
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2309
diff changeset
    21
    util,
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    22
)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    23
2328
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
    24
from mercurial.i18n import _
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
    25
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    26
from . import (
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    27
    exthelper,
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    28
)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    29
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    30
eh = exthelper.exthelper()
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    31
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    32
try:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    33
    obsstorefilecache = localrepo.localrepository.obsstore
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    34
except AttributeError:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    35
    # XXX hg-3.8 compat
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    36
    #
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    37
    # mercurial 3.8 has issue with accessing file cache property from their
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    38
    # cache. This is fix by 36fbd72c2f39fef8ad52d7c559906c2bc388760c in core
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    39
    # and shipped in 3.9
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    40
    obsstorefilecache = localrepo.localrepository.__dict__['obsstore']
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    41
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    42
# obsstore is a filecache so we have do to some spacial dancing
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    43
@eh.wrapfunction(obsstorefilecache, 'func')
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    44
def obsstorewithcache(orig, repo):
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    45
    obsstore = orig(repo)
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    46
    obsstore.obscache = obscache(repo.unfiltered())
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    47
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    48
    class cachekeyobsstore(obsstore.__class__):
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    49
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    50
        _obskeysize = 200
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    51
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    52
        def cachekey(self, index=None):
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    53
            """return (current-length, cachekey)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    54
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    55
            'current-length': is the current length of the obsstore storage file,
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    56
            'cachekey' is the hash of the last 200 bytes ending at 'index'.
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    57
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    58
            if 'index' is unspecified, current obsstore length is used.
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    59
            Cacheckey will be set to null id if the obstore is empty.
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    60
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    61
            If the index specified is higher than the current obsstore file
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    62
            length, cachekey will be set to None."""
2306
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    63
            # default value
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    64
            obsstoresize = 0
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    65
            keydata = ''
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    66
            # try to get actual data from the obsstore
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    67
            try:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    68
                with self.svfs('obsstore') as obsfile:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    69
                    obsfile.seek(0, 2)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    70
                    obsstoresize = obsfile.tell()
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    71
                    if index is None:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    72
                        index = obsstoresize
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    73
                    elif obsstoresize < index:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    74
                        return obsstoresize, None
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    75
                    actualsize = min(index, self._obskeysize)
2306
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    76
                    if actualsize:
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    77
                        obsfile.seek(index - actualsize, 0)
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    78
                        keydata = obsfile.read(actualsize)
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    79
            except (OSError, IOError) as e:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    80
                if e.errno != errno.ENOENT:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    81
                    raise
2306
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    82
            key = hashlib.sha1(keydata).digest()
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    83
            return obsstoresize, key
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    84
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    85
    obsstore.__class__ = cachekeyobsstore
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    86
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    87
    return obsstore
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    88
2307
0d2e0e8e76f6 obscache: set a valid "empty" cache key if the cache is missing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2306
diff changeset
    89
emptykey = (node.nullrev, node.nullid, 0, 0, node.nullid)
0d2e0e8e76f6 obscache: set a valid "empty" cache key if the cache is missing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2306
diff changeset
    90
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    91
def upgradeneeded(repo, key):
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    92
    """return (valid, start-rev, start-obs-idx)
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    93
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    94
    'valid': is "False" if older cache value needs invalidation,
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    95
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    96
    'start-rev': first revision not in the cache. None if cache is up to date,
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    97
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    98
    'start-obs-idx': index of the first obs-markers not in the cache. None is
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    99
                     up to date.
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   100
    """
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   101
2346
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   102
    # We need to ensure we use the same changelog and obsstore through the
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   103
    # processing. Otherwise some invalidation could update the object and their
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   104
    # content after we computed the cache key.
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   105
    cl = repo.changelog
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   106
    obsstore = repo.obsstore
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   107
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   108
    reset = False
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   109
2343
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   110
    status = _checkkey(repo, key)
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   111
    if status is None:
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   112
        reset = True
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   113
        key = emptykey
2346
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   114
        obssize, obskey = obsstore.cachekey()
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   115
        tiprev = len(cl) - 1
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   116
    else:
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   117
        tiprev, obssize, obskey = status
2343
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   118
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   119
    keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   120
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   121
    if not reset and keytiprev == tiprev and keyobssize == obssize:
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   122
        return None # nothing to upgrade
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   123
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   124
    ### cache is valid, is there anything to update
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   125
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   126
    # any new changesets ?
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   127
    revs = ()
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   128
    if keytiprev < tiprev:
2346
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   129
        revs = list(cl.revs(start=keytiprev + 1, stop=tiprev))
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   130
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   131
    # any new markers
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   132
    markers = ()
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   133
    if keyobssize < obssize:
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   134
        # XXX Three are a small race change here. Since the obsstore might have
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   135
        # move forward between the time we computed the cache key and we access
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   136
        # the data. To fix this we need so "up to" argument when fetching the
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   137
        # markers here. Otherwise we might return more markers than covered by
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   138
        # the cache key.
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   139
        #
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   140
        # In pratice the cache is only updated after each transaction within a
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   141
        # lock. So we should be fine. We could enforce this with a new repository
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   142
        # requirement (or fix the race, that is not too hard).
2346
34c6382dbb82 obscache: guard from changing changelog or obsstore object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2345
diff changeset
   143
        markers = markersfrom(obsstore, keyobssize, keyobslength)
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   144
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   145
    return reset, revs, markers, (obssize, obskey)
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   146
2343
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   147
def _checkkey(repo, key):
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   148
    """internal function"""
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   149
    if key is None:
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   150
        return None
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   151
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   152
    ### Is the cache valid ?
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   153
    keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   154
    # check for changelog strip
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   155
    cl = repo.changelog
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   156
    tiprev = len(cl) - 1
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   157
    if (tiprev < keytiprev
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   158
            or cl.node(keytiprev) != keytipnode):
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   159
        return None
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   160
    # check for obsstore strip
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   161
    obssize, obskey = repo.obsstore.cachekey(index=keyobssize)
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   162
    if obskey != keyobskey:
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   163
        return None
37749a3cd3d1 obscache: extract the cache key validation in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2334
diff changeset
   164
    return tiprev, obssize, obskey
2328
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   165
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   166
# XXX copied as is from Mercurial 4.2 and added the "offset" parameters
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   167
@util.nogc
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   168
def _readmarkers(data, offset=None):
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   169
    """Read and enumerate markers from raw data"""
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   170
    off = 0
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   171
    diskversion = struct.unpack('>B', data[off:off + 1])[0]
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   172
    if offset is None:
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   173
        off += 1
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   174
    else:
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   175
        assert 1 <= offset
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   176
        off = offset
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   177
    if diskversion not in obsolete.formats:
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   178
        raise error.Abort(_('parsing obsolete marker: unknown version %r')
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   179
                          % diskversion)
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   180
    return diskversion, obsolete.formats[diskversion][0](data, off)
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   181
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   182
def markersfrom(obsstore, byteoffset, firstmarker):
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   183
    if not firstmarker:
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   184
        return list(obsstore)
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   185
    elif '_all' in vars(obsstore):
2328
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   186
        # if the data are in memory, just use that
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   187
        return obsstore._all[firstmarker:]
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   188
    else:
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   189
        obsdata = obsstore.svfs.tryread('obsstore')
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   190
        return _readmarkers(obsdata, byteoffset)[1]
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
   191
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   192
class obscache(object):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   193
    """cache the "does a rev" is the precursors of some obsmarkers data
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   194
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   195
    This is not directly holding the "is this revision obsolete" information,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   196
    because phases data gets into play here. However, it allow to compute the
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   197
    "obsolescence" set without reading the obsstore content.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   198
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   199
    Implementation note #1:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   200
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   201
      The obsstore is implementing only half of the transaction logic it
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   202
      should. It properly record the starting point of the obsstore to allow
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   203
      clean rollback. However it still write to the obsstore file directly
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   204
      during the transaction. Instead it should be keeping data in memory and
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   205
      write to a '.pending' file to make the data vailable for hooks.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   206
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   207
      This cache is not going futher than what the obstore is doing, so it does
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   208
      not has any '.pending' logic. When the obsstore gains proper '.pending'
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   209
      support, adding it to this cache should not be too hard. As the flag
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   210
      always move from 0 to 1, we could have a second '.pending' cache file to
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   211
      be read. If flag is set in any of them, the value is 1. For the same
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   212
      reason, updating the file in place should be possible.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   213
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   214
    Implementation note #2:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   215
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   216
      Instead of having a large final update run, we could update this cache at
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   217
      the level adding a new changeset or a new obsmarkers. More on this in the
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   218
      'update code'.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   219
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   220
    Implementation note #3:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   221
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   222
        Storage-wise, we could have a "start rev" to avoid storing useless
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   223
        zero. That would be especially useful for the '.pending' overlay.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   224
    """
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   225
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   226
    _filepath = 'cache/evoext-obscache-00'
2302
acd2431dff29 obscache: update the format to allow negative tiprev
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2301
diff changeset
   227
    _headerformat = '>q20sQQ20s'
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   228
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   229
    def __init__(self, repo):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   230
        self._vfs = repo.vfs
2334
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   231
        # cache key covering the changesets and obsmarkers content
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   232
        #
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   233
        # It contains the following data. Combined with 'upgradeneeded' it allows to
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   234
        # do iterative upgrade for cache depending of theses two pieces of data.
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   235
        #
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   236
        # The cache key parts are"
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   237
        # - tip-rev,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   238
        # - tip-node,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   239
        # - obsstore-length (nb markers),
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   240
        # - obsstore-file-size (in bytes),
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   241
        # - obsstore "cache key"
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   242
        self._cachekey = None
2309
9f09cabe679e obscache: skip writing to disk if the data did not changed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2308
diff changeset
   243
        self._ondiskkey = None
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   244
        self._data = bytearray()
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   245
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   246
    def get(self, rev):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   247
        """return True if "rev" is used as "precursors for any obsmarkers
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   248
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   249
        Make sure the cache has been updated to match the repository content before using it"""
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   250
        return self._data[rev]
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   251
2333
adf114c767ab obscache: distinct 'clear' and 'reset'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2330
diff changeset
   252
    def clear(self, reset=False):
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   253
        """invalidate the cache content"""
2333
adf114c767ab obscache: distinct 'clear' and 'reset'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2330
diff changeset
   254
        self._cachekey = emptykey if reset else None
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   255
        self._data = bytearray()
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   256
2300
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   257
    def uptodate(self, repo):
2301
54b2fddbc2f5 obscache: load the disk data before checking is the cache is up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2300
diff changeset
   258
        if self._cachekey is None:
54b2fddbc2f5 obscache: load the disk data before checking is the cache is up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2300
diff changeset
   259
            self.load(repo)
2344
827d0f0a483f obscache: use the smaller scope function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2343
diff changeset
   260
        status = _checkkey(repo, self._cachekey)
827d0f0a483f obscache: use the smaller scope function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2343
diff changeset
   261
        return (status is not None
827d0f0a483f obscache: use the smaller scope function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2343
diff changeset
   262
                and status[0] == self._cachekey[0] # tiprev
827d0f0a483f obscache: use the smaller scope function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2343
diff changeset
   263
                and status[1] == self._cachekey[3]) # obssize
2300
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   264
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   265
    def update(self, repo):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   266
        """Iteratively update the cache with new repository data"""
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   267
        # If we do not have any data, try loading from disk
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   268
        if self._cachekey is None:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   269
            self.load(repo)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   270
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   271
        assert repo.filtername is None
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   272
        cl = repo.changelog
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   273
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   274
        upgrade = upgradeneeded(repo, self._cachekey)
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   275
        if upgrade is None:
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   276
            return
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   277
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   278
        reset, revs, obsmarkers, obskeypair = upgrade
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   279
        if reset or self._cachekey is None:
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   280
            self.clear(reset=True)
2325
04a0eda7dea9 obscache: move assert earlier in the code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2316
diff changeset
   281
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   282
        if revs:
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   283
            self._updaterevs(repo, revs)
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   284
            assert len(self._data) == len(cl), (len(self._data), len(cl))
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   285
        if obsmarkers:
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   286
            self._updatemarkers(repo, obsmarkers)
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   287
2334
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   288
        # update the key from the new data
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   289
        key = list(self._cachekey)
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   290
        if revs:
2334
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   291
            key[0] = len(cl) - 1
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   292
            key[1] = cl.node(key[0])
2345
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   293
        if obsmarkers:
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   294
            key[2] += len(obsmarkers)
406c1a57b4ee obscache: return the new data along-side the upgrade needs (and cache key)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2344
diff changeset
   295
            key[3], key[4] = obskeypair
2334
b31ef65a846a obscache: update the cache key in place
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2333
diff changeset
   296
        self._cachekey = tuple(key)
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   297
2326
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   298
    def _updaterevs(self, repo, revs):
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   299
        """update the cache with new revisions
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   300
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   301
        Newly added changeset might be affected by obsolescence markers
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   302
        we already have locally. So we needs to have some global
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   303
        knowledge about the markers to handle that question.
2326
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   304
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   305
        Right now this requires parsing all markers in the obsstore. We could
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   306
        imagine using various optimisation (eg: another cache, network
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   307
        exchange, etc).
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   308
2330
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   309
        A possible approach to this is to build a set of all node used as
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   310
        precursors in `obsstore._obscandidate`. If markers are not loaded yet,
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   311
        we could initialize it by doing a quick scan through the obsstore data
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   312
        and filling a (pre-sized) set. Doing so would be much faster than
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   313
        parsing all the obsmarkers since we would access less data, not create
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   314
        any object beside the nodes and not have to decode any complex data.
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   315
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   316
        For now we stick to the simpler approach of paying the
2326
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   317
        performance cost on new changesets.
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   318
        """
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   319
        node = repo.changelog.node
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   320
        succs = repo.obsstore.successors
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   321
        for r in revs:
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   322
            if node(r) in succs:
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   323
                val = 1
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   324
            else:
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   325
                val = 0
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   326
            self._data.append(val)
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   327
2327
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   328
    def _updatemarkers(self, repo, obsmarkers):
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   329
        """update the cache with new markers"""
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   330
        rev = repo.changelog.nodemap.get
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   331
        for m in obsmarkers:
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   332
            r = rev(m[0])
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   333
            if r is not None:
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   334
                self._data[r] = 1
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   335
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   336
    def save(self, repo):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   337
        """save the data to disk"""
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   338
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   339
        # XXX it happens that the obsstore is (buggilly) always up to date on disk
2309
9f09cabe679e obscache: skip writing to disk if the data did not changed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2308
diff changeset
   340
        if self._cachekey is None or self._cachekey == self._ondiskkey:
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   341
            return
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   342
2316
35a548465647 compat: drop the context manager used to write the cache file
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2315
diff changeset
   343
        cachefile = repo.vfs(self._filepath, 'w', atomictemp=True)
35a548465647 compat: drop the context manager used to write the cache file
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2315
diff changeset
   344
        headerdata = struct.pack(self._headerformat, *self._cachekey)
35a548465647 compat: drop the context manager used to write the cache file
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2315
diff changeset
   345
        cachefile.write(headerdata)
35a548465647 compat: drop the context manager used to write the cache file
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2315
diff changeset
   346
        cachefile.write(self._data)
35a548465647 compat: drop the context manager used to write the cache file
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2315
diff changeset
   347
        cachefile.close()
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   348
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   349
    def load(self, repo):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   350
        """load data from disk"""
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   351
        assert repo.filtername is None
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   352
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   353
        data = repo.vfs.tryread(self._filepath)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   354
        if not data:
2307
0d2e0e8e76f6 obscache: set a valid "empty" cache key if the cache is missing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2306
diff changeset
   355
            self._cachekey = emptykey
2309
9f09cabe679e obscache: skip writing to disk if the data did not changed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2308
diff changeset
   356
            self._data = bytearray()
9f09cabe679e obscache: skip writing to disk if the data did not changed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2308
diff changeset
   357
        else:
9f09cabe679e obscache: skip writing to disk if the data did not changed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2308
diff changeset
   358
            headersize = struct.calcsize(self._headerformat)
9f09cabe679e obscache: skip writing to disk if the data did not changed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2308
diff changeset
   359
            self._cachekey = struct.unpack(self._headerformat, data[:headersize])
9f09cabe679e obscache: skip writing to disk if the data did not changed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2308
diff changeset
   360
            self._data = bytearray(data[headersize:])
9f09cabe679e obscache: skip writing to disk if the data did not changed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2308
diff changeset
   361
        self._ondiskkey = self._cachekey
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   362
2300
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   363
def _computeobsoleteset(orig, repo):
2298
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   364
    """the set of obsolete revisions"""
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   365
    obs = set()
2300
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   366
    repo = repo.unfiltered()
2315
e16f6bef5848 compat: make obscache code compatible with Mercurial version prior to 4.2
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2309
diff changeset
   367
    if util.safehasattr(repo._phasecache, 'getrevset'):
e16f6bef5848 compat: make obscache code compatible with Mercurial version prior to 4.2
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2309
diff changeset
   368
        notpublic = repo._phasecache.getrevset(repo, (phases.draft, phases.secret))
e16f6bef5848 compat: make obscache code compatible with Mercurial version prior to 4.2
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2309
diff changeset
   369
    else:
e16f6bef5848 compat: make obscache code compatible with Mercurial version prior to 4.2
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2309
diff changeset
   370
        # < hg-4.2 compat
e16f6bef5848 compat: make obscache code compatible with Mercurial version prior to 4.2
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2309
diff changeset
   371
        notpublic = repo.revs("not public()")
2298
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   372
    if notpublic:
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   373
        obscache = repo.obsstore.obscache
2300
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   374
        # Since we warm the cache at the end of every transaction, the cache
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   375
        # should be up to date. However a non-enabled client might have touched
2300
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   376
        # the repository.
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   377
        #
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   378
        # Updating the cache without a lock is sloppy, so we fallback to the
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   379
        # old method and rely on the fact the next transaction will write the
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   380
        # cache down anyway.
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   381
        #
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   382
        # With the current implementation updating the cache will requires to
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   383
        # load the obsstore anyway. Once loaded, hitting the obsstore directly
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   384
        # will be about as fast...
2300
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   385
        if not obscache.uptodate(repo):
2304
2f15090712fe obscache: still update and use the cache during transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2303
diff changeset
   386
            if repo.currenttransaction() is None:
2305
a786240c95bd obscache: log case where the cache is not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2304
diff changeset
   387
                repo.ui.log('evoext-obscache',
a786240c95bd obscache: log case where the cache is not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2304
diff changeset
   388
                            'obscache is out of date, '
a786240c95bd obscache: log case where the cache is not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2304
diff changeset
   389
                            'falling back to slower obsstore version\n')
a786240c95bd obscache: log case where the cache is not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2304
diff changeset
   390
                repo.ui.debug('obscache is out of date')
2304
2f15090712fe obscache: still update and use the cache during transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2303
diff changeset
   391
                return orig(repo)
2f15090712fe obscache: still update and use the cache during transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2303
diff changeset
   392
            else:
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   393
                # If a transaction is open, it is worthwhile to update and use
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   394
                # the cache, the lock prevent race and it will be written on
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   395
                # disk when the transaction close.
2304
2f15090712fe obscache: still update and use the cache during transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2303
diff changeset
   396
                obscache.update(repo)
2298
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   397
        isobs = obscache.get
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   398
    for r in notpublic:
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   399
        if isobs(r):
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   400
            obs.add(r)
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   401
    return obs
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   402
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   403
@eh.uisetup
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   404
def cachefuncs(ui):
2300
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   405
    orig = obsolete.cachefuncs['obsolete']
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   406
    wrapped = lambda repo: _computeobsoleteset(orig, repo)
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   407
    obsolete.cachefuncs['obsolete'] = wrapped
2298
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   408
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   409
@eh.reposetup
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   410
def setupcache(ui, repo):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   411
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   412
    class obscacherepo(repo.__class__):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   413
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   414
        @localrepo.unfilteredmethod
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   415
        def destroyed(self):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   416
            if 'obsstore' in vars(self):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   417
                self.obsstore.obscache.clear()
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   418
2297
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   419
        def transaction(self, *args, **kwargs):
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   420
            tr = super(obscacherepo, self).transaction(*args, **kwargs)
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   421
            reporef = weakref.ref(self)
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   422
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   423
            def _warmcache(tr):
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   424
                repo = reporef()
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   425
                if repo is None:
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   426
                    return
2303
8534400111fd obscache: warm the cache in all cases
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2302
diff changeset
   427
                repo = repo.unfiltered()
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   428
                # As pointed in 'obscache.update', we could have the changelog
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   429
                # and the obsstore in charge of updating the cache when new
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   430
                # items goes it. The tranaction logic would then only be
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   431
                # involved for the 'pending' and final writing on disk.
2303
8534400111fd obscache: warm the cache in all cases
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2302
diff changeset
   432
                self.obsstore.obscache.update(repo)
8534400111fd obscache: warm the cache in all cases
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2302
diff changeset
   433
                self.obsstore.obscache.save(repo)
2297
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   434
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   435
            tr.addpostclose('warmcache-obscache', _warmcache)
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   436
            return tr
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   437
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   438
    repo.__class__ = obscacherepo