hgext3rd/evolve/obscache.py
author Anton Shestakov <av6@dwimlabs.net>
Sun, 26 Jan 2020 20:57:20 +0700
branchstable
changeset 5247 5a2e7c6f9174
parent 4957 e8302f760a54
child 5137 4fef6b157175
permissions -rw-r--r--
touch: use repo.setparents() instead of repo.dirstate.setparents() setparents() was added to localrepository class in 2012, and now we finally have some differences between calling repo.setparents() vs repo.dirstate.setparents(): _quick_access_* things, introduced in hg 5.3. This patch fixes potential quick-access desync problems where repo[b'.'] would be different from repo.dirstate.p1().
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
2424
4afbcdcfa9b2 compat: handle lack of 'util.timer' for pre 4.2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2387
diff changeset
    10
import errno
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
    11
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
    12
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
    13
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
from mercurial import (
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
    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
    16
    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
    17
    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
    18
    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
    19
    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
    20
)
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
    21
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    22
from . import (
4957
e8302f760a54 compat: compatibility for cl.nodemap.get vs cl.index.get_rev
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
    23
    compat,
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    24
    exthelper,
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    25
)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    26
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    27
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
    28
3144
6f10c94a2114 compat: stop working around 3.8 file cache limitation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3036
diff changeset
    29
obsstorefilecache = localrepo.localrepository.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
    30
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    31
# 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
    32
@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
    33
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
    34
    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
    35
    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
    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
    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
    38
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    39
        _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
    40
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    41
        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
    42
            """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
    43
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    44
            '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
    45
            '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
    46
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    47
            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
    48
            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
    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
            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
    51
            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
    52
            # default value
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    53
            obsstoresize = 0
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
    54
            keydata = b''
2306
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    55
            # 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
    56
            try:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
    57
                with self.svfs(b'obsstore') as obsfile:
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    58
                    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
    59
                    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
    60
                    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
    61
                        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
    62
                    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
    63
                        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
    64
                    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
    65
                    if actualsize:
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    66
                        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
    67
                        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
    68
            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
    69
                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
    70
                    raise
2354
fed22455e510 obscache: use 'nullid' as the hash of an empty obsstore
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2353
diff changeset
    71
            if keydata:
fed22455e510 obscache: use 'nullid' as the hash of an empty obsstore
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2353
diff changeset
    72
                key = hashlib.sha1(keydata).digest()
fed22455e510 obscache: use 'nullid' as the hash of an empty obsstore
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2353
diff changeset
    73
            else:
fed22455e510 obscache: use 'nullid' as the hash of an empty obsstore
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2353
diff changeset
    74
                # reusing an existing "empty" value make it easier to define a
fed22455e510 obscache: use 'nullid' as the hash of an empty obsstore
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2353
diff changeset
    75
                # default cachekey for 'no data'.
fed22455e510 obscache: use 'nullid' as the hash of an empty obsstore
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2353
diff changeset
    76
                key = node.nullid
2306
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    77
            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
    78
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    79
    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
    80
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    81
    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
    82
2328
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
    83
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
    84
    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
    85
        return list(obsstore)
4804
079dbf36e884 python3: add raw prefix in cases harder to analyze at the token level
Raphaël Gomès <rgomes@octobus.net>
parents: 4758
diff changeset
    86
    elif r'_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
    87
        # 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
    88
        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
    89
    else:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
    90
        obsdata = obsstore.svfs.tryread(b'obsstore')
3687
50f1968724f0 obscache: drop compat layer for obsmarkers reading
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3685
diff changeset
    91
        return obsolete._readmarkers(obsdata, byteoffset)[1]
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    92
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    93
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
    94
class dualsourcecache(object):
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
    95
    """An abstract class for cache that needs both changelog and 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
    96
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
    97
    This class handle the tracking of changelog and obsstore update. It provide
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
    98
    data to performs incremental update (see the 'updatefrom' function for
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
    99
    details).  This class can also detect stripping of the changelog or the
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   100
    obsstore and can reset the cache in this cache (see the 'clear' function
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   101
    for details).
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   102
    """
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   103
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   104
    # default key used for an empty cache
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   105
    #
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   106
    # The cache key covering the changesets and obsmarkers content
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   107
    #
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   108
    # The cache key parts are:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   109
    # - tip-rev,
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   110
    # - tip-node,
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   111
    # - obsstore-length (nb markers),
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   112
    # - obsstore-file-size (in bytes),
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   113
    # - obsstore "cache key"
2353
393cbaf0d294 obcache: move empty on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2352
diff changeset
   114
    emptykey = (node.nullrev, node.nullid, 0, 0, node.nullid)
2376
12386f7f5056 dualsourcecache: add a cache name
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2375
diff changeset
   115
    _cachename = None # used for error message
2353
393cbaf0d294 obcache: move empty on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2352
diff changeset
   116
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   117
    def __init__(self):
2359
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   118
        super(dualsourcecache, self).__init__()
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
   119
        self._cachekey = None
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   120
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   121
    def _updatefrom(self, repo, revs, obsmarkers):
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   122
        """override this method to update your cache data incrementally
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
   123
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   124
        revs:      list of new revision in the changelog
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   125
        obsmarker: list of new obsmarkers in the obsstore
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   126
        """
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   127
        raise NotImplementedError
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
   128
2333
adf114c767ab obscache: distinct 'clear' and 'reset'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2330
diff changeset
   129
    def clear(self, reset=False):
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   130
        """invalidate the cache content
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   131
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   132
        if 'reset' is passed, we detected a strip and the cache will have to be
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   133
        recomputed.
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   134
        """
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   135
        # /!\ IMPORTANT /!\
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   136
        # You must overide this method to actually
2387
a41d900d015c dualsourcecache: simplify cachekey.clear
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2385
diff changeset
   137
        if reset:
a41d900d015c dualsourcecache: simplify cachekey.clear
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2385
diff changeset
   138
            self._cachekey = self.emptykey if reset else None
a41d900d015c dualsourcecache: simplify cachekey.clear
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2385
diff changeset
   139
        else:
a41d900d015c dualsourcecache: simplify cachekey.clear
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2385
diff changeset
   140
            self._cachekey = None
2359
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   141
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   142
    def load(self, repo):
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   143
        """Load data from disk
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   144
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   145
        Do not forget to restore the "cachekey" attribute while doing so.
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   146
        """
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   147
        raise NotImplementedError
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   148
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   149
    # Useful public function (no need to override them)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   150
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   151
    def uptodate(self, repo):
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   152
        """return True if the cache content is up to date False otherwise
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   153
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   154
        This method can be used to detect of the cache is lagging behind new
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   155
        data in either changelog or obsstore.
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   156
        """
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   157
        if self._cachekey is None:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   158
            self.load(repo)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   159
        status = self._checkkey(repo.changelog, repo.obsstore)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   160
        return (status is not None
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   161
                and status[0] == self._cachekey[0] # tiprev
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   162
                and status[1] == self._cachekey[3]) # obssize
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   163
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   164
    def update(self, repo):
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   165
        """update the cache with new repository data
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   166
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   167
        The update will be incremental when possible"""
2359
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   168
        repo = repo.unfiltered()
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   169
        # If we do not have any data, try loading from disk
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   170
        if self._cachekey is None:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   171
            self.load(repo)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   172
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   173
        assert repo.filtername is None
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   174
        cl = repo.changelog
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   175
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   176
        upgrade = self._upgradeneeded(repo)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   177
        if upgrade is None:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   178
            return
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   179
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   180
        reset, revs, obsmarkers, obskeypair = upgrade
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   181
        if reset or self._cachekey is None:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   182
            repo.ui.log(b'evoext-cache', b'strip detected, %s cache reset\n' % self._cachename)
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   183
            self.clear(reset=True)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   184
3685
bf000d1a525f timer: drop compat layer for time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3645
diff changeset
   185
        starttime = util.timer()
3507
c0b6a95b94b9 pure: make sure what we expect to be list are list
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3409
diff changeset
   186
        revs = list(revs)
c0b6a95b94b9 pure: make sure what we expect to be list are list
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3409
diff changeset
   187
        obsmarkers = list(obsmarkers)
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   188
        self._updatefrom(repo, revs, obsmarkers)
3685
bf000d1a525f timer: drop compat layer for time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3645
diff changeset
   189
        duration = util.timer() - starttime
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   190
        repo.ui.log(b'evoext-cache', b'updated %s in %.4f seconds (%dr, %do)\n',
2380
694494619795 cache: track time spend updating various cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2379
diff changeset
   191
                    self._cachename, duration, len(revs), len(obsmarkers))
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   192
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   193
        # update the key from the new data
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   194
        key = list(self._cachekey)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   195
        if revs:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   196
            key[0] = len(cl) - 1
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   197
            key[1] = cl.node(key[0])
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   198
        if obsmarkers:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   199
            key[2] += len(obsmarkers)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   200
            key[3], key[4] = obskeypair
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   201
        self._cachekey = tuple(key)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   202
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   203
    # from here, there are internal function only
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
   204
2352
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   205
    def _checkkey(self, changelog, obsstore):
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   206
        """internal function"""
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   207
        key = self._cachekey
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   208
        if key is None:
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   209
            return None
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   210
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   211
        ### Is the cache valid ?
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   212
        keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   213
        # check for changelog strip
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   214
        tiprev = len(changelog) - 1
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   215
        if (tiprev < keytiprev
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   216
                or changelog.node(keytiprev) != keytipnode):
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   217
            return None
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   218
        # check for obsstore strip
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   219
        obssize, obskey = obsstore.cachekey(index=keyobssize)
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   220
        if obskey != keyobskey:
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   221
            return None
2385
fab59e2cb05f dualsourcecache: fix obskey return by _checkkey
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2382
diff changeset
   222
        if obssize != keyobssize:
fab59e2cb05f dualsourcecache: fix obskey return by _checkkey
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2382
diff changeset
   223
            # we want to return the obskey for the new size
fab59e2cb05f dualsourcecache: fix obskey return by _checkkey
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2382
diff changeset
   224
            __, obskey = obsstore.cachekey(index=obssize)
2352
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   225
        return tiprev, obssize, obskey
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   226
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   227
    def _upgradeneeded(self, repo):
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   228
        """return (valid, start-rev, start-obs-idx)
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   229
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   230
        'valid': is "False" if older cache value needs invalidation,
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   231
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   232
        'start-rev': first revision not in the cache. None if cache is up to date,
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   233
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   234
        'start-obs-idx': index of the first obs-markers not in the cache. None is
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   235
                         up to date.
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   236
        """
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   237
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   238
        # We need to ensure we use the same changelog and obsstore through the
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   239
        # processing. Otherwise some invalidation could update the object and their
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   240
        # content after we computed the cache key.
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   241
        cl = repo.changelog
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   242
        obsstore = repo.obsstore
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   243
        key = self._cachekey
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   244
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   245
        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
   246
2352
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   247
        status = self._checkkey(cl, obsstore)
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   248
        if status is None:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   249
            reset = True
2353
393cbaf0d294 obcache: move empty on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2352
diff changeset
   250
            key = self.emptykey
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   251
            obssize, obskey = obsstore.cachekey()
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   252
            tiprev = len(cl) - 1
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   253
        else:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   254
            tiprev, obssize, obskey = status
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   255
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   256
        keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   257
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   258
        if not reset and keytiprev == tiprev and keyobssize == obssize:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   259
            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
   260
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   261
        ### cache is valid, is there anything to update
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   262
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   263
        # any new changesets ?
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   264
        revs = ()
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   265
        if keytiprev < tiprev:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   266
            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
   267
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   268
        # any new markers
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   269
        markers = ()
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   270
        if keyobssize < obssize:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   271
            # XXX Three are a small race change here. Since the obsstore might have
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   272
            # move forward between the time we computed the cache key and we access
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   273
            # the data. To fix this we need so "up to" argument when fetching the
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   274
            # markers here. Otherwise we might return more markers than covered by
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   275
            # the cache key.
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   276
            #
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   277
            # In pratice the cache is only updated after each transaction within a
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   278
            # lock. So we should be fine. We could enforce this with a new repository
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   279
            # requirement (or fix the race, that is not too hard).
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   280
            markers = markersfrom(obsstore, keyobssize, keyobslength)
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
   281
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   282
        return reset, revs, markers, (obssize, obskey)
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   283
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   284
class obscache(dualsourcecache):
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
   285
    """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
   286
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
    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
   288
    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
   289
    "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
   290
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
   291
    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
   292
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
   293
      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
   294
      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
   295
      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
   296
      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
   297
      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
   298
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
   299
      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
   300
      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
   301
      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
   302
      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
   303
      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
   304
      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
   305
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
   306
    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
   307
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
   308
      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
   309
      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
   310
      '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
   311
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
   312
    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
   313
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
   314
        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
   315
        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
   316
    """
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
   317
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   318
    _filepath = b'evoext-obscache-00'
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   319
    _headerformat = b'>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
   320
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   321
    _cachename = b'evo-ext-obscache' # used for error message
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
   322
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
   323
    def __init__(self, repo):
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   324
        super(obscache, self).__init__()
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   325
        self._ondiskkey = None
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   326
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   327
    @util.propertycache
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   328
    def get(self):
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   329
        """final signature: obscache.get(rev)
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   330
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   331
        return True if "rev" is used as "precursors for any 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
   332
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   333
        IMPORTANT: make sure the cache has been updated to match the repository
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   334
        content before using it
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
   335
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   336
        We use a property cache to skip the attribute resolution overhead in
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   337
        hot loops."""
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   338
        return self._data.__getitem__
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   339
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   340
    def _setdata(self, data):
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   341
        """set a new bytearray data, invalidating the 'get' shortcut if needed"""
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   342
        self._data = data
4804
079dbf36e884 python3: add raw prefix in cases harder to analyze at the token level
Raphaël Gomès <rgomes@octobus.net>
parents: 4758
diff changeset
   343
        if r'get' in vars(self):
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   344
            del self.get
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
   345
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   346
    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
   347
        """invalidate the cache content"""
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   348
        super(obscache, self).clear(reset=reset)
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   349
        self._setdata(bytearray())
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
   350
2356
d5de0529a48f obscache: extract the actual data update in a dedicated function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2355
diff changeset
   351
    def _updatefrom(self, repo, revs, obsmarkers):
d5de0529a48f obscache: extract the actual data update in a dedicated function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2355
diff changeset
   352
        if revs:
d5de0529a48f obscache: extract the actual data update in a dedicated function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2355
diff changeset
   353
            self._updaterevs(repo, revs)
d5de0529a48f obscache: extract the actual data update in a dedicated function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2355
diff changeset
   354
        if obsmarkers:
d5de0529a48f obscache: extract the actual data update in a dedicated function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2355
diff changeset
   355
            self._updatemarkers(repo, obsmarkers)
d5de0529a48f obscache: extract the actual data update in a dedicated function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2355
diff changeset
   356
2326
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   357
    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
   358
        """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
   359
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   360
        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
   361
        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
   362
        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
   363
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   364
        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
   365
        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
   366
        exchange, etc).
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
   367
2330
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   368
        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
   369
        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
   370
        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
   371
        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
   372
        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
   373
        any object beside the nodes and not have to decode any complex data.
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
   374
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   375
        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
   376
        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
   377
        """
2570
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   378
        new_entries = bytearray(len(revs))
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   379
        if not self._data:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   380
            self._setdata(new_entries)
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   381
        else:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   382
            self._data.extend(new_entries)
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   383
        data = self._data
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   384
        if repo.obsstore:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   385
            node = repo.changelog.node
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   386
            succs = repo.obsstore.successors
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   387
            for r in revs:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   388
                if node(r) in succs:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   389
                    data[r] = 1
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
   390
2327
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   391
    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
   392
        """update the cache with new markers"""
4957
e8302f760a54 compat: compatibility for cl.nodemap.get vs cl.index.get_rev
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   393
        getrev = compat.getgetrev(repo.changelog)
2327
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   394
        for m in obsmarkers:
4957
e8302f760a54 compat: compatibility for cl.nodemap.get vs cl.index.get_rev
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   395
            r = getrev(m[0])
2327
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   396
            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
   397
                self._data[r] = 1
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
   398
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
   399
    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
   400
        """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
   401
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
   402
        # 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
   403
        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
   404
            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
   405
4097
4ea2a813b82c obscache: ignore permission and OS errors when writing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3975
diff changeset
   406
        try:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   407
            cachefile = repo.cachevfs(self._filepath, b'w', atomictemp=True)
4097
4ea2a813b82c obscache: ignore permission and OS errors when writing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3975
diff changeset
   408
            headerdata = struct.pack(self._headerformat, *self._cachekey)
4ea2a813b82c obscache: ignore permission and OS errors when writing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3975
diff changeset
   409
            cachefile.write(headerdata)
4ea2a813b82c obscache: ignore permission and OS errors when writing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3975
diff changeset
   410
            cachefile.write(self._data)
4ea2a813b82c obscache: ignore permission and OS errors when writing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3975
diff changeset
   411
            cachefile.close()
4098
c9fc82c4e66d obscache: update the variable tracking on disk state after write
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 4097
diff changeset
   412
            self._ondiskkey = self._cachekey
4097
4ea2a813b82c obscache: ignore permission and OS errors when writing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3975
diff changeset
   413
        except (IOError, OSError) as exc:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   414
            repo.ui.log(b'obscache', b'could not write update %s\n' % exc)
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   415
            repo.ui.debug(b'obscache: could not write update %s\n' % exc)
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
   416
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
    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
   418
        """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
   419
        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
   420
4488
6c0992ce05f7 compat: drop getcachevfs, repo.cachevfs is supported in hg 4.4
Joerg Sonnenberger <joerg@bec.de>
parents: 4109
diff changeset
   421
        data = repo.cachevfs.tryread(self._filepath)
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
   422
        if not data:
2353
393cbaf0d294 obcache: move empty on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2352
diff changeset
   423
            self._cachekey = self.emptykey
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   424
            self._setdata(bytearray())
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
   425
        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
   426
            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
   427
            self._cachekey = struct.unpack(self._headerformat, data[:headersize])
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   428
            self._setdata(bytearray(data[headersize:]))
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
   429
        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
   430
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
   431
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
   432
    """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
   433
    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
   434
    repo = repo.unfiltered()
3688
bda024010aed obscache: drop compat layer to access public changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3687
diff changeset
   435
    notpublic = repo._phasecache.getrevset(repo, (phases.draft, phases.secret))
2298
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   436
    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
   437
        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
   438
        # 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
   439
        # 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
   440
        # 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
   441
        #
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   442
        # 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
   443
        # 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
   444
        # 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
   445
        #
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   446
        # 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
   447
        # 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
   448
        # 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
   449
        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
   450
            if repo.currenttransaction() is None:
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   451
                repo.ui.log(b'evoext-cache',
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   452
                            b'obscache is out of date, '
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   453
                            b'falling back to slower obsstore version\n')
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   454
                repo.ui.debug(b'obscache is out of date\n')
2304
2f15090712fe obscache: still update and use the cache during transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2303
diff changeset
   455
                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
   456
            else:
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   457
                # 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
   458
                # 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
   459
                # 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
   460
                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
   461
        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
   462
    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
   463
        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
   464
            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
   465
    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
   466
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   467
@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
   468
def cachefuncs(ui):
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   469
    orig = obsolete.cachefuncs[b'obsolete']
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
   470
    wrapped = lambda repo: _computeobsoleteset(orig, repo)
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   471
    obsolete.cachefuncs[b'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
   472
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
   473
@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
   474
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
   475
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
   476
    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
   477
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
   478
        @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
   479
        def destroyed(self):
4804
079dbf36e884 python3: add raw prefix in cases harder to analyze at the token level
Raphaël Gomès <rgomes@octobus.net>
parents: 4758
diff changeset
   480
            if r'obsstore' in vars(self):
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
   481
                self.obsstore.obscache.clear()
2367
3be45918c7b5 evolve: fixing obscache invalidation
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 2316
diff changeset
   482
            super(obscacherepo, self).destroyed()
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
   483
3968
37178a2d3557 compat: drop compatibility layer for updatecaches
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3688
diff changeset
   484
        @localrepo.unfilteredmethod
37178a2d3557 compat: drop compatibility layer for updatecaches
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3688
diff changeset
   485
        def updatecaches(self, tr=None, **kwargs):
37178a2d3557 compat: drop compatibility layer for updatecaches
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3688
diff changeset
   486
            super(obscacherepo, self).updatecaches(tr, **kwargs)
37178a2d3557 compat: drop compatibility layer for updatecaches
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3688
diff changeset
   487
            self.obsstore.obscache.update(self)
37178a2d3557 compat: drop compatibility layer for updatecaches
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3688
diff changeset
   488
            self.obsstore.obscache.save(self)
2297
32cdcf493567 perf: warm the cache after all transactions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2296
diff changeset
   489
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
   490
    repo.__class__ = obscacherepo