hgext3rd/evolve/obscache.py
author Anton Shestakov <av6@dwimlabs.net>
Fri, 08 May 2020 19:49:07 +0800
branchmercurial-5.3
changeset 5361 51b8024878e9
parent 5176 b9af7b8f3eee
permissions -rw-r--r--
test-compat: back out changeset 591a0afd2ef3
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
5176
b9af7b8f3eee compat: drop import compatibility <= 4.5 for `forcebytestr`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 5137
diff changeset
    22
from mercurial.utils.stringutil import forcebytestr
5137
4fef6b157175 py3-exceptions: wrap more Exceptions in forcebytestr before formatting
willstott101@gmail.com
parents: 4929
diff changeset
    23
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
from . import (
4929
bb2b4f6c99dc compat: compatibility for cl.nodemap.get vs cl.index.get_rev
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
    25
    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
    26
    exthelper,
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    27
)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    28
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    29
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
    30
3144
6f10c94a2114 compat: stop working around 3.8 file cache limitation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3036
diff changeset
    31
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
    32
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    33
# 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
    34
@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
    35
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
    36
    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
    37
    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
    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
    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
    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
        _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
    42
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    43
        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
    44
            """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
    45
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    46
            '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
    47
            '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
    48
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    49
            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
    50
            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
    51
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    52
            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
    53
            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
    54
            # default value
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    55
            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
    56
            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
    57
            # 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
    58
            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
    59
                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
    60
                    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
    61
                    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
    62
                    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
    63
                        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
    64
                    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
    65
                        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
    66
                    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
    67
                    if actualsize:
b33bc2f37e89 obscache: have the obsstore fix empty file cachekey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2305
diff changeset
    68
                        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
    69
                        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
    70
            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
    71
                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
    72
                    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
    73
            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
    74
                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
    75
            else:
fed22455e510 obscache: use 'nullid' as the hash of an empty obsstore
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2353
diff changeset
    76
                # 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
    77
                # 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
    78
                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
    79
            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
    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
    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
    82
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    83
    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
    84
2328
7ccacaa38782 obscache: Only access the new obsmarkers for marker update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2327
diff changeset
    85
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
    86
    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
    87
        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
    88
    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
    89
        # 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
    90
        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
    91
    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
    92
        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
    93
        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
    94
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    95
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
    96
class dualsourcecache(object):
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
    97
    """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
    98
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
    99
    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
   100
    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
   101
    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
   102
    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
   103
    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
   104
    """
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   105
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   106
    # 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
   107
    #
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   108
    # 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
   109
    #
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   110
    # The cache key parts are:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   111
    # - tip-rev,
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   112
    # - tip-node,
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   113
    # - obsstore-length (nb markers),
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   114
    # - obsstore-file-size (in bytes),
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   115
    # - obsstore "cache key"
2353
393cbaf0d294 obcache: move empty on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2352
diff changeset
   116
    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
   117
    _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
   118
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   119
    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
   120
        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
   121
        self._cachekey = None
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   122
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   123
    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
   124
        """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
   125
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   126
        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
   127
        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
   128
        """
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   129
        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
   130
2333
adf114c767ab obscache: distinct 'clear' and 'reset'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2330
diff changeset
   131
    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
   132
        """invalidate the cache content
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   133
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   134
        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
   135
        recomputed.
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   136
        """
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   137
        # /!\ IMPORTANT /!\
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   138
        # 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
   139
        if reset:
a41d900d015c dualsourcecache: simplify cachekey.clear
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2385
diff changeset
   140
            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
   141
        else:
a41d900d015c dualsourcecache: simplify cachekey.clear
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2385
diff changeset
   142
            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
   143
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   144
    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
   145
        """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
   146
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   147
        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
   148
        """
ff635fa59a25 obscache: makes dualsourcecache compatible with obshashrange cache needs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2357
diff changeset
   149
        raise NotImplementedError
2357
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
    # 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
   152
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   153
    def uptodate(self, repo):
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   154
        """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
   155
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   156
        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
   157
        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
   158
        """
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   159
        if self._cachekey is None:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   160
            self.load(repo)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   161
        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
   162
        return (status is not None
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   163
                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
   164
                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
   165
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   166
    def update(self, repo):
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   167
        """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
   168
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   169
        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
   170
        repo = repo.unfiltered()
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   171
        # 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
   172
        if self._cachekey is None:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   173
            self.load(repo)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   174
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   175
        assert repo.filtername is None
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   176
        cl = repo.changelog
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   177
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   178
        upgrade = self._upgradeneeded(repo)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   179
        if upgrade is None:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   180
            return
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   181
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   182
        reset, revs, obsmarkers, obskeypair = upgrade
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   183
        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
   184
            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
   185
            self.clear(reset=True)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   186
3685
bf000d1a525f timer: drop compat layer for time
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3645
diff changeset
   187
        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
   188
        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
   189
        obsmarkers = list(obsmarkers)
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   190
        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
   191
        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
   192
        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
   193
                    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
   194
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   195
        # 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
   196
        key = list(self._cachekey)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   197
        if revs:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   198
            key[0] = len(cl) - 1
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   199
            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
   200
        if obsmarkers:
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   201
            key[2] += len(obsmarkers)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   202
            key[3], key[4] = obskeypair
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   203
        self._cachekey = tuple(key)
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   204
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   205
    # 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
   206
2352
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   207
    def _checkkey(self, changelog, obsstore):
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   208
        """internal function"""
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   209
        key = self._cachekey
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   210
        if key is None:
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   211
            return None
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   212
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   213
        ### Is the cache valid ?
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   214
        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
   215
        # check for changelog strip
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   216
        tiprev = len(changelog) - 1
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   217
        if (tiprev < keytiprev
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   218
                or changelog.node(keytiprev) != keytipnode):
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   219
            return None
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   220
        # check for obsstore strip
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   221
        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
   222
        if obskey != keyobskey:
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   223
            return None
2385
fab59e2cb05f dualsourcecache: fix obskey return by _checkkey
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2382
diff changeset
   224
        if obssize != keyobssize:
fab59e2cb05f dualsourcecache: fix obskey return by _checkkey
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2382
diff changeset
   225
            # 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
   226
            __, 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
   227
        return tiprev, obssize, obskey
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   228
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   229
    def _upgradeneeded(self, repo):
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   230
        """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
   231
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   232
        '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
   233
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   234
        '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
   235
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   236
        '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
   237
                         up to date.
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   238
        """
2295
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   239
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   240
        # 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
   241
        # 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
   242
        # 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
   243
        cl = repo.changelog
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   244
        obsstore = repo.obsstore
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   245
        key = self._cachekey
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   246
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   247
        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
   248
2352
dd8471e54708 obcache: move _checkkey on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2351
diff changeset
   249
        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
   250
        if status is None:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   251
            reset = True
2353
393cbaf0d294 obcache: move empty on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2352
diff changeset
   252
            key = self.emptykey
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   253
            obssize, obskey = obsstore.cachekey()
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   254
            tiprev = len(cl) - 1
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   255
        else:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   256
            tiprev, obssize, obskey = status
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
        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
   259
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   260
        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
   261
            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
   262
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   263
        ### 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
   264
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   265
        # any new changesets ?
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   266
        revs = ()
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   267
        if keytiprev < tiprev:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   268
            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
   269
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   270
        # any new markers
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   271
        markers = ()
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   272
        if keyobssize < obssize:
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   273
            # 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
   274
            # 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
   275
            # 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
   276
            # 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
   277
            # the cache key.
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   278
            #
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   279
            # 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
   280
            # 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
   281
            # 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
   282
            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
   283
2351
1bec5ee99674 obcache: move updateneeded on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2347
diff changeset
   284
        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
   285
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   286
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
   287
    """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
   288
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
    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
   290
    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
   291
    "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
   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
    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
   294
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
      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
   296
      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
   297
      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
   298
      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
   299
      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
   300
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
      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
   302
      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
   303
      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
   304
      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
   305
      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
   306
      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
   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
    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
   309
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
      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
   311
      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
   312
      '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
   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
    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
   315
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
        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
   317
        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
   318
    """
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
   319
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   320
    _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
   321
    _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
   322
4814
48b30ff742cb python3: use format-source to run byteify-strings in .py files
Raphaël Gomès <rgomes@octobus.net>
parents: 4804
diff changeset
   323
    _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
   324
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
   325
    def __init__(self, repo):
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   326
        super(obscache, self).__init__()
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   327
        self._ondiskkey = None
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   328
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   329
    @util.propertycache
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   330
    def get(self):
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   331
        """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
   332
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   333
        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
   334
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   335
        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
   336
        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
   337
2552
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   338
        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
   339
        hot loops."""
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   340
        return self._data.__getitem__
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   341
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   342
    def _setdata(self, data):
006400e25e22 obscache: shortcut the attribute access for testing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2424
diff changeset
   343
        """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
   344
        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
   345
        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
   346
            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
   347
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   348
    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
   349
        """invalidate the cache content"""
2357
f787f5406a98 obscache: extract a data agnostic class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2356
diff changeset
   350
        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
   351
        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
   352
2356
d5de0529a48f obscache: extract the actual data update in a dedicated function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2355
diff changeset
   353
    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
   354
        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
   355
            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
   356
        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
   357
            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
   358
2326
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   359
    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
   360
        """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
   361
72853bade853 obscache: extract code to update from new revision
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2325
diff changeset
   362
        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
   363
        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
   364
        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
   365
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   366
        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
   367
        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
   368
        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
   369
2330
d72c8c1f09e2 obscache: document a possible way forward to skipping obsstore parsing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2329
diff changeset
   370
        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
   371
        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
   372
        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
   373
        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
   374
        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
   375
        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
   376
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   377
        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
   378
        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
   379
        """
2570
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   380
        new_entries = bytearray(len(revs))
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   381
        if not self._data:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   382
            self._setdata(new_entries)
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   383
        else:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   384
            self._data.extend(new_entries)
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   385
        data = self._data
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   386
        if repo.obsstore:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   387
            node = repo.changelog.node
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   388
            succs = repo.obsstore.successors
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   389
            for r in revs:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   390
                if node(r) in succs:
86959f2c625d obscache: directly allocate zeroed bytearray
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2569
diff changeset
   391
                    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
   392
2327
6b751daad348 obscache: extract _updatemarkers code into its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2326
diff changeset
   393
    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
   394
        """update the cache with new markers"""
4929
bb2b4f6c99dc compat: compatibility for cl.nodemap.get vs cl.index.get_rev
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   395
        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
   396
        for m in obsmarkers:
4929
bb2b4f6c99dc compat: compatibility for cl.nodemap.get vs cl.index.get_rev
Anton Shestakov <av6@dwimlabs.net>
parents: 4814
diff changeset
   397
            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
   398
            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
   399
                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
   400
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
    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
   402
        """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
   403
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
        # 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
   405
        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
   406
            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
   407
4097
4ea2a813b82c obscache: ignore permission and OS errors when writing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3975
diff changeset
   408
        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
   409
            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
   410
            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
   411
            cachefile.write(headerdata)
4ea2a813b82c obscache: ignore permission and OS errors when writing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3975
diff changeset
   412
            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
   413
            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
   414
            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
   415
        except (IOError, OSError) as exc:
5137
4fef6b157175 py3-exceptions: wrap more Exceptions in forcebytestr before formatting
willstott101@gmail.com
parents: 4929
diff changeset
   416
            repo.ui.log(b'obscache', b'could not write update %s\n' % forcebytestr(exc))
4fef6b157175 py3-exceptions: wrap more Exceptions in forcebytestr before formatting
willstott101@gmail.com
parents: 4929
diff changeset
   417
            repo.ui.debug(b'obscache: could not write update %s\n' % forcebytestr(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
   418
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
    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
   420
        """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
   421
        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
   422
4488
6c0992ce05f7 compat: drop getcachevfs, repo.cachevfs is supported in hg 4.4
Joerg Sonnenberger <joerg@bec.de>
parents: 4109
diff changeset
   423
        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
   424
        if not data:
2353
393cbaf0d294 obcache: move empty on the class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2352
diff changeset
   425
            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
   426
            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
   427
        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
   428
            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
   429
            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
   430
            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
   431
        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
   432
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
   433
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
   434
    """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
   435
    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
   436
    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
   437
    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
   438
    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
   439
        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
   440
        # 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
   441
        # 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
   442
        # 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
   443
        #
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
        # 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
   445
        # 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
   446
        # 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
   447
        #
01efebff13ec obscache: skip the cache entirely if not up to date
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2298
diff changeset
   448
        # 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
   449
        # 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
   450
        # 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
   451
        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
   452
            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
   453
                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
   454
                            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
   455
                            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
   456
                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
   457
                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
   458
            else:
2329
3bb8382fc4cb obscache: update some documentation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2328
diff changeset
   459
                # 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
   460
                # 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
   461
                # 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
   462
                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
   463
        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
   464
    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
   465
        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
   466
            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
   467
    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
   468
8199204274f0 perf: use the cache to compute the obsolete set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2297
diff changeset
   469
@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
   470
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
   471
    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
   472
    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
   473
    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
   474
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
   475
@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
   476
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
   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
    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
   479
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
   480
        @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
   481
        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
   482
            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
   483
                self.obsstore.obscache.clear()
2367
3be45918c7b5 evolve: fixing obscache invalidation
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 2316
diff changeset
   484
            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
   485
3968
37178a2d3557 compat: drop compatibility layer for updatecaches
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3688
diff changeset
   486
        @localrepo.unfilteredmethod
37178a2d3557 compat: drop compatibility layer for updatecaches
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3688
diff changeset
   487
        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
   488
            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
   489
            self.obsstore.obscache.update(self)
37178a2d3557 compat: drop compatibility layer for updatecaches
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3688
diff changeset
   490
            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
   491
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
   492
    repo.__class__ = obscacherepo