hgext3rd/evolve/obscache.py
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
Mon, 01 May 2017 08:13:24 +0200
changeset 2296 d6584ce58030
parent 2295 017b971ba28f
child 2297 32cdcf493567
permissions -rw-r--r--
perf: adds a cache to know if obsmarkers might affect a revision Phase information still needs to be thrown in the mix to compute the final information, but skipping reading the obsstore for most operation is a large win. Usage of this cache arrives in the next changeset.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     1
# Code dedicated to an cache around obsolescence property
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     2
#
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     3
# This module content aims at being upstreamed.
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     4
#
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     5
# Copyright 2017 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     6
#
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     7
# This software may be used and distributed according to the terms of the
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     8
# GNU General Public License version 2 or any later version.
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     9
2296
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    10
import hashlib
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    11
import struct
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    12
import weakref
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    13
import errno
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    14
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    15
from mercurial import (
d6584ce58030 perf: 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
    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
    17
    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
    18
    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
    19
    node,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    20
)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
    21
2294
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    22
from . import (
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    23
    exthelper,
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    24
)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    25
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    26
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
    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
try:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    29
    obsstorefilecache = localrepo.localrepository.obsstore
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    30
except AttributeError:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    31
    # XXX hg-3.8 compat
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    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
    # mercurial 3.8 has issue with accessing file cache property from their
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    34
    # cache. This is fix by 36fbd72c2f39fef8ad52d7c559906c2bc388760c in core
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    35
    # and shipped in 3.9
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    36
    obsstorefilecache = localrepo.localrepository.__dict__['obsstore']
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    37
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    38
# 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
    39
@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
    40
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
    41
    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
    42
    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
    43
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    44
    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
    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
        _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
    47
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    48
        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
    49
            """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
    50
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    51
            '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
    52
            '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
    53
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    54
            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
    55
            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
    56
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    57
            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
    58
            length, cachekey will be set to None."""
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    59
            try:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    60
                with self.svfs('obsstore') as obsfile:
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    61
                    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
    62
                    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
    63
                    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
    64
                        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
    65
                    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
    66
                        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
    67
                    actualsize = min(index, self._obskeysize)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    68
                    obsfile.seek(index - actualsize, 0)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    69
                    keydata = obsfile.read(actualsize)
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    70
                return obsstoresize, hashlib.sha1(keydata).digest()
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    71
            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
    72
                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
    73
                    raise
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    74
                return 0, node.nullid
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    75
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    76
    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
    77
75996eafab43 perf: adds some cache key helper on the obsstore class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    78
    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
    79
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    80
def getcachekey(repo):
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    81
    """get a cache key covering the changesets and obsmarkers content
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    82
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    83
    IT contains the following data. Combined with 'upgradeneeded' it allows to
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    84
    do iterative upgrade for cache depending of theses two data.
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    85
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    86
    The cache key parts are"
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    87
    - tip-rev,
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    88
    - tip-node,
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    89
    - obsstore-length (nb markers),
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    90
    - obsstore-file-size (in bytes),
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    91
    - obsstore "cache key"
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    92
    """
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    93
    assert repo.filtername is None
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    94
    cl = repo.changelog
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    95
    index, key = repo.obsstore.cachekey()
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    96
    tiprev = len(cl) - 1
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    97
    return (tiprev,
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    98
            cl.node(tiprev),
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
    99
            len(repo.obsstore),
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   100
            index,
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   101
            key)
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   102
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   103
def upgradeneeded(repo, key):
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   104
    """return (valid, start-rev, start-obs-idx)
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   105
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   106
    'valid': is "False" if older cache value needs invalidation,
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   107
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   108
    'start-rev': first revision not in the cache. None if cache is up to date,
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   109
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   110
    'start-obs-idx': index of the first obs-markers not in the cache. None is
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   111
                     up to date.
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   112
    """
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   113
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   114
    # XXX ideally, this function would return a bounded amount of changeset and
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   115
    # obsmarkers and the associated new cache key. Otherwise we are exposed to
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   116
    # a race condition between the time the cache is updated and the new cache
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   117
    # key is computed. (however, we do not want to compute the full new cache
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   118
    # key in all case because we want to skip reading the obsstore content. We
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   119
    # could have a smarter implementation here.
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   120
    #
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   121
    # In pratice the cache should be updated after each transaction within a
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   122
    # lock. So we should be fine. We could enforce this with a new repository
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   123
    # requirement (or fix the race, that is not too hard).
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   124
    invalid = (False, 0, 0)
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   125
    if key is None:
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   126
        return invalid
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   127
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   128
    ### Is the cache valid ?
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   129
    keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   130
    # check for changelog strip
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   131
    cl = repo.changelog
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   132
    tiprev = len(cl) - 1
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   133
    if (tiprev < keytiprev
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   134
            or cl.node(keytiprev) != keytipnode):
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   135
        return invalid
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   136
    # check for obsstore strip
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   137
    obssize, obskey = repo.obsstore.cachekey(index=keyobssize)
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   138
    if obskey != keyobskey:
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   139
        return invalid
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   140
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   141
    ### cache is valid, is there anything to update
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   142
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   143
    # any new changesets ?
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   144
    startrev = None
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   145
    if keytiprev < tiprev:
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   146
        startrev = keytiprev + 1
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   147
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   148
    # any new markers
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   149
    startidx = None
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   150
    if keyobssize < obssize:
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   151
        startidx = keyobslength
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   152
017b971ba28f perf: adds cachekey utility to validate changelog+obsstore content
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2294
diff changeset
   153
    return True, startrev, startidx
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
   154
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   155
class obscache(object):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   156
    """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
   157
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   158
    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
   159
    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
   160
    "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
   161
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   162
    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
   163
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   164
      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
   165
      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
   166
      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
   167
      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
   168
      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
   169
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   170
      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
   171
      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
   172
      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
   173
      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
   174
      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
   175
      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
   176
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   177
    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
   178
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   179
      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
   180
      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
   181
      '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
   182
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   183
    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
   184
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   185
        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
   186
        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
   187
    """
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   188
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   189
    _filepath = 'cache/evoext-obscache-00'
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   190
    _headerformat = '>I20sQQ20s'
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   191
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   192
    def __init__(self, repo):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   193
        self._vfs = repo.vfs
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   194
        # The cache key parts are"
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   195
        # - tip-rev,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   196
        # - tip-node,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   197
        # - obsstore-length (nb markers),
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   198
        # - obsstore-file-size (in bytes),
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   199
        # - obsstore "cache key"
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   200
        self._cachekey = 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
   201
        self._data = bytearray()
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   202
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   203
    def get(self, rev):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   204
        """return True if "rev" is used as "precursors for any obsmarkers
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   205
d6584ce58030 perf: 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
        Make sure the cache has been updated to match the repository content before using it"""
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   207
        return self._data[rev]
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   208
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   209
    def clear(self):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   210
        """invalidate the cache 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
   211
        self._cachekey = 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
   212
        self._data = bytearray()
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   213
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   214
    def update(self, repo):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   215
        """Iteratively update the cache with new repository data"""
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   216
        # If we do not have any data, try loading from disk
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   217
        if self._cachekey is None:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   218
            self.load(repo)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   219
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   220
        valid, startrev, startidx = upgradeneeded(repo, self._cachekey)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   221
        if not valid:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   222
            self.clear()
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   223
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   224
        if startrev is None and startidx 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
   225
            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
   226
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   227
        # process the new changesets
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   228
        cl = repo.changelog
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   229
        if startrev is not 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
   230
            node = cl.node
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   231
            # Note:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   232
            #
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   233
            #  Newly added changeset might be affected by obsolescence markers
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   234
            #  we already have locally. So we needs to have soem global
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   235
            #  knowledge about the markers to handle that question. Right this
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   236
            #  requires parsing all markers in the obsstore. However, we could
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   237
            #  imagine using various optimisation (eg: bloom filter, other on
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   238
            #  disk cache) to remove this full parsing.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   239
            #
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   240
            #  For now we stick to the simpler approach or paying 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
   241
            #  performance cost on new changesets.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   242
            succs = repo.obsstore.successors
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   243
            for r in cl.revs(startrev):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   244
                if node(r) in succs:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   245
                    val = 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
   246
                else:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   247
                    val = 0
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   248
                self._data.append(val)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   249
        assert len(self._data) == len(cl), (len(self._data), len(cl))
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   250
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   251
        # process the new obsmarkers
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   252
        if startidx is not 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
   253
            rev = cl.nodemap.get
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   254
            markers = repo.obsstore._all
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   255
            # Note:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   256
            #
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   257
            #   There are no actually needs to load the full obsstore here,
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   258
            #   since we only read the latest ones.  We do it for simplicity in
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   259
            #   the first implementation. Loading the full obsstore has a
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   260
            #   performance cost and should go away in this case too. We have
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   261
            #   two simples options for that:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   262
            #
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   263
            #   1) provide and API to start reading markers from a byte offset
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   264
            #      (we have that data in the cache key)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   265
            #
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   266
            #   2) directly update the cache at a lower level, in the 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
   267
            #      responsible for adding a markers.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   268
            #
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   269
            #   Option 2 is probably a bit more invasive, but more solid on the long run
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   270
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   271
            for i in xrange(startidx, len(repo.obsstore)):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   272
                r = rev(markers[i][0])
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   273
                # If markers affect a newly added nodes, it would have been
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   274
                # caught in the previous loop, (so we skip < startrev)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   275
                if r is not None and (startrev is None or r < startrev):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   276
                    self._data[r] = 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
   277
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   278
        # XXX note that there are a race condition here, since the repo "might"
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   279
        # have changed side the cache update above. However, this code will
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   280
        # mostly be running in a lock so we ignore the issue for now.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   281
        #
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   282
        # To work around this, 'upgradeneeded' should return a bounded amount
d6584ce58030 perf: 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
        # of changeset and markers to read with their associated cachekey. see
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   284
        # 'upgradeneeded' for detail.
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   285
        self._cachekey = getcachekey(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
   286
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   287
    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
   288
        """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
   289
d6584ce58030 perf: 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
        # XXX it happens that the obsstore is (buggilly) always up to date on 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
   291
        if self._cachekey is None:
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   292
            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
   293
d6584ce58030 perf: 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
        with repo.vfs(self._filepath, 'w', atomictemp=True) as cachefile:
d6584ce58030 perf: 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
            headerdata = struct.pack(self._headerformat, *self._cachekey)
d6584ce58030 perf: 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
            cachefile.write(headerdata)
d6584ce58030 perf: 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
            cachefile.write(self._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
   298
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   299
    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
   300
        """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
   301
        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
   302
d6584ce58030 perf: 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
        data = repo.vfs.tryread(self._filepath)
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   304
        if not 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
   305
            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
   306
d6584ce58030 perf: 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
        headersize = struct.calcsize(self._headerformat)
d6584ce58030 perf: 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
        self._cachekey = struct.unpack(self._headerformat, data[:headersize])
d6584ce58030 perf: 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
        self._data = bytearray(data[headersize:])
d6584ce58030 perf: 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
d6584ce58030 perf: 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
@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
   312
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
   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
    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
   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
        @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
   317
        def destroyed(self):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   318
            if 'obsstore' in vars(self):
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   319
                self.obsstore.obscache.clear()
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   320
d6584ce58030 perf: adds a cache to know if obsmarkers might affect a revision
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2295
diff changeset
   321
    repo.__class__ = obscacherepo