hgext3rd/evolve/stablerangecache.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 21 Dec 2017 03:30:13 +0100
changeset 3346 f4e28b781143
parent 3344 4d054737a79c
child 3347 ab5172ba3c81
permissions -rw-r--r--
stablerange: use mergepoint based algorithm for the official stable range Changing the official stable range will impact all users of the infrastructure. We update version number of the cache file and discovery methods to clarify this. We do no keep compatibility with the old method over the wire. The new algorithm is much better and keeping compat is more work than we have time for right now.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3308
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
     1
import abc
3342
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
     2
import heapq
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
     3
import sqlite3
3342
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
     4
import time
2238
aac765e84de3 stablerange: warm cache on transaction (if obshashrange is enabled)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2237
diff changeset
     5
import weakref
2130
d784622dd5dc stablerange: move the range class in the new module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2129
diff changeset
     6
2125
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     7
from mercurial import (
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
     8
    error,
2125
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     9
    localrepo,
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    10
    util,
2125
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    11
)
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    12
3307
a1ab2588a628 stablerange: split pure algorithm part from the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3306
diff changeset
    13
from . import (
a1ab2588a628 stablerange: split pure algorithm part from the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3306
diff changeset
    14
    exthelper,
3342
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    15
    genericcaches,
3307
a1ab2588a628 stablerange: split pure algorithm part from the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3306
diff changeset
    16
    stablerange,
3346
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
    17
    utility,
3307
a1ab2588a628 stablerange: split pure algorithm part from the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3306
diff changeset
    18
)
a1ab2588a628 stablerange: split pure algorithm part from the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3306
diff changeset
    19
2129
d07bb7cbae2f stablesort: move into the stablerange module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2128
diff changeset
    20
from mercurial.i18n import _
d07bb7cbae2f stablesort: move into the stablerange module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2128
diff changeset
    21
2125
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    22
eh = exthelper.exthelper()
3307
a1ab2588a628 stablerange: split pure algorithm part from the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3306
diff changeset
    23
eh.merge(stablerange.eh)
3342
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    24
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    25
class stablerangeondiskbase(stablerange.stablerangecached,
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    26
                            genericcaches.changelogsourcebase):
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    27
    """combine the generic stablerange cache usage with generic changelog one
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    28
    """
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    29
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    30
    def _updatefrom(self, repo, data):
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    31
        """compute the rev of one revision, assert previous revision has an hot cache
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    32
        """
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    33
        repo = repo.unfiltered()
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    34
        ui = repo.ui
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    35
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    36
        rangeheap = []
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    37
        for r in data:
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    38
            rangeheap.append((r, 0))
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    39
        total = len(data)
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    40
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    41
        heappop = heapq.heappop
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    42
        heappush = heapq.heappush
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    43
        heapify = heapq.heapify
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    44
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    45
        original = set(rangeheap)
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    46
        seen = 0
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    47
        # progress report is showing up in the profile for small and fast
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    48
        # repository so we only update it every so often
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    49
        progress_each = 100
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    50
        progress_last = time.time()
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    51
        heapify(rangeheap)
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    52
        while rangeheap:
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    53
            rangeid = heappop(rangeheap)
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    54
            if rangeid in original:
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    55
                if not seen % progress_each:
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    56
                    # if a lot of time passed, report more often
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    57
                    progress_new = time.time()
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    58
                    if (1 < progress_each) and (0.1 < progress_new - progress_last):
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    59
                        progress_each /= 10
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    60
                    ui.progress(_("filling stablerange cache"), seen, total=total)
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    61
                    progress_last = progress_new
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    62
                seen += 1
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    63
                original.remove(rangeid) # might have been added from other source
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    64
            rangeid = rangeid
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    65
            if self._getsub(rangeid) is None:
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    66
                for sub in self.subranges(repo, rangeid):
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    67
                    if self._getsub(sub) is None:
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    68
                        heappush(rangeheap, sub)
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    69
        ui.progress(_("filling stablerange cache"), None, total=total)
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    70
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    71
    def clear(self, reset=False):
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    72
        super(stablerangeondiskbase, self).clear()
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    73
        self._subrangescache.clear()
3194aec207ae stablerange: add a base class for on disk stored stablerange class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3308
diff changeset
    74
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    75
#############################
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    76
### simple sqlite caching ###
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    77
#############################
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    78
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    79
_sqliteschema = [
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    80
    """CREATE TABLE meta(schemaversion INTEGER NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    81
                         tiprev        INTEGER NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    82
                         tipnode       BLOB    NOT NULL
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    83
                        );""",
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    84
    """CREATE TABLE range(rev INTEGER  NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    85
                          idx INTEGER NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    86
                          PRIMARY KEY(rev, idx));""",
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    87
    """CREATE TABLE subranges(listidx INTEGER NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    88
                              suprev  INTEGER NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    89
                              supidx  INTEGER NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    90
                              subrev  INTEGER NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    91
                              subidx  INTEGER NOT NULL,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    92
                              PRIMARY KEY(listidx, suprev, supidx),
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    93
                              FOREIGN KEY (suprev, supidx) REFERENCES range(rev, idx),
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    94
                              FOREIGN KEY (subrev, subidx) REFERENCES range(rev, idx)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    95
    );""",
2240
ecb993892c61 stablerange: warm cache before using it server side
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2238
diff changeset
    96
    "CREATE INDEX subranges_index ON subranges (suprev, supidx);",
ecb993892c61 stablerange: warm cache before using it server side
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2238
diff changeset
    97
    "CREATE INDEX range_index ON range (rev, idx);",
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    98
]
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
    99
_newmeta = "INSERT INTO meta (schemaversion, tiprev, tipnode) VALUES (?,?,?);"
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   100
_updatemeta = "UPDATE meta SET tiprev = ?, tipnode = ?;"
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   101
_updaterange = "INSERT INTO range(rev, idx) VALUES (?,?);"
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   102
_updatesubranges = """INSERT
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   103
                       INTO subranges(listidx, suprev, supidx, subrev, subidx)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   104
                       VALUES (?,?,?,?,?);"""
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   105
_queryexist = "SELECT name FROM sqlite_master WHERE type='table' AND name='meta';"
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   106
_querymeta = "SELECT schemaversion, tiprev, tipnode FROM meta;"
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   107
_queryrange = "SELECT * FROM range WHERE (rev = ? AND idx = ?);"
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   108
_querysubranges = """SELECT subrev, subidx
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   109
                     FROM subranges
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   110
                     WHERE (suprev = ? AND supidx = ?)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   111
                     ORDER BY listidx;"""
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   112
3308
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   113
class stablerangesqlbase(stablerange.stablerangecached):
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   114
    """class that can handle all the bits needed to store range into sql
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   115
    """
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   116
3308
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   117
    __metaclass__ = abc.ABCMeta
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   118
3308
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   119
    _schemaversion = None
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   120
    _cachefile = None
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   121
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   122
    def __init__(self, repo, **kwargs):
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   123
        super(stablerangesqlbase, self).__init__(**kwargs)
2400
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   124
        self._vfs = repo.vfs
3308
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   125
        self._path = repo.vfs.join(self._cachefile)
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   126
        self._cl = repo.unfiltered().changelog # (okay to keep an old one)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   127
        self._ondisktiprev = None
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   128
        self._ondisktipnode = None
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   129
        self._unsavedsubranges = {}
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   130
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   131
    def _getsub(self, rangeid):
3308
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   132
        # 1) check the in memory cache
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   133
        # 2) check the sqlcaches (and warm in memory cache we want we find)
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   134
        cache = self._subrangescache
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   135
        if rangeid not in cache and rangeid[0] <= self._ondisktiprev and self._con is not None:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   136
            value = None
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   137
            result = self._con.execute(_queryrange, rangeid).fetchone()
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   138
            if result is not None: # database know about this node (skip in the future?)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   139
                value = self._con.execute(_querysubranges, rangeid).fetchall()
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   140
            # in memory caching of the value
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   141
            cache[rangeid] = value
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   142
        return cache.get(rangeid)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   143
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   144
    def _setsub(self, rangeid, value):
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   145
        assert rangeid not in self._unsavedsubranges
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   146
        self._unsavedsubranges[rangeid] = value
3308
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   147
        super(stablerangesqlbase, self)._setsub(rangeid, value)
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   148
2400
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   149
    def _db(self):
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   150
        try:
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   151
            util.makedirs(self._vfs.dirname(self._path))
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   152
        except OSError:
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   153
            return None
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   154
        con = sqlite3.connect(self._path)
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   155
        con.text_factory = str
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   156
        return con
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   157
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   158
    @util.propertycache
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   159
    def _con(self):
2400
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   160
        con = self._db()
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   161
        if con is None:
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   162
            return None
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   163
        cur = con.execute(_queryexist)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   164
        if cur.fetchone() is None:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   165
            return None
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   166
        meta = con.execute(_querymeta).fetchone()
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   167
        if meta is None:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   168
            return None
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   169
        if meta[0] != self._schemaversion:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   170
            return None
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   171
        if len(self._cl) <= meta[1]:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   172
            return None
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   173
        if self._cl.node(meta[1]) != meta[2]:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   174
            return None
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   175
        self._ondisktiprev = meta[1]
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   176
        self._ondisktipnode = meta[2]
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   177
        if self._tiprev < self._ondisktiprev:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   178
            self._tiprev = self._ondisktiprev
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   179
            self._tipnode = self._ondisktipnode
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   180
        return con
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   181
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   182
    def _save(self, repo):
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   183
        repo = repo.unfiltered()
3240
9361149224a7 depthcache: move to a dedicated object and storage
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3236
diff changeset
   184
        repo.depthcache.save(repo)
9361149224a7 depthcache: move to a dedicated object and storage
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3236
diff changeset
   185
        if not self._unsavedsubranges:
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   186
            return # no new data
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   187
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   188
        if self._con is None:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   189
            util.unlinkpath(self._path, ignoremissing=True)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   190
            if '_con' in vars(self):
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   191
                del self._con
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   192
2400
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   193
            con = self._db()
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   194
            if con is None:
9a53ed7e5540 stablerangecache: avoid crash when 'cache/' directory is missing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2381
diff changeset
   195
                return
2237
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   196
            with con:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   197
                for req in _sqliteschema:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   198
                    con.execute(req)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   199
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   200
                meta = [self._schemaversion,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   201
                        self._tiprev,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   202
                        self._tipnode,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   203
                ]
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   204
                con.execute(_newmeta, meta)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   205
        else:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   206
            con = self._con
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   207
            meta = con.execute(_querymeta).fetchone()
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   208
            if meta[2] != self._ondisktipnode or meta[1] != self._ondisktiprev:
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   209
                # drifting is currently an issue because this means another
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   210
                # process might have already added the cache line we are about
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   211
                # to add. This will confuse sqlite
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   212
                msg = _('stable-range cache: skipping write, '
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   213
                        'database drifted under my feet\n')
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   214
                hint = _('(disk: %s-%s vs mem: %s%s)\n')
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   215
                data = (meta[2], meta[1], self._ondisktiprev, self._ondisktipnode)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   216
                repo.ui.warn(msg)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   217
                repo.ui.warn(hint % data)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   218
                return
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   219
            meta = [self._tiprev,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   220
                    self._tipnode,
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   221
            ]
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   222
            con.execute(_updatemeta, meta)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   223
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   224
        self._saverange(con, repo)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   225
        con.commit()
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   226
        self._ondisktiprev = self._tiprev
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   227
        self._ondisktipnode = self._tipnode
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   228
        self._unsavedsubranges.clear()
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   229
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   230
    def _saverange(self, con, repo):
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   231
        repo = repo.unfiltered()
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   232
        data = []
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   233
        allranges = set()
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   234
        for key, value in self._unsavedsubranges.items():
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   235
            allranges.add(key)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   236
            for idx, sub in enumerate(value):
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   237
                data.append((idx, key[0], key[1], sub[0], sub[1]))
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   238
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   239
        con.executemany(_updaterange, allranges)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   240
        con.executemany(_updatesubranges, data)
98e0369b548b stablerange: introduce ondisk caching through sqlite
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2236
diff changeset
   241
3343
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   242
class stablerangesql(stablerangesqlbase, stablerangeondiskbase):
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   243
    """base clase able to preserve data to disk as sql"""
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   244
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   245
    __metaclass__ = abc.ABCMeta
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   246
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   247
    # self._cachekey = (tiprev, tipnode)
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   248
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   249
    @property
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   250
    def _tiprev(self):
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   251
        return self._cachekey[0]
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   252
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   253
    @_tiprev.setter
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   254
    def _tiprev(self, value):
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   255
        self._cachekey = (value, self._cachekey[1])
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   256
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   257
    @property
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   258
    def _tipnode(self):
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   259
        return self._cachekey[1]
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   260
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   261
    @_tipnode.setter
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   262
    def _tipnode(self, value):
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   263
        self._cachekey = (self._cachekey[0], value)
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   264
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   265
    def clear(self, reset=False):
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   266
        super(stablerangesql, self).clear(reset=reset)
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   267
        del self._con
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   268
        self._subrangescache.clear()
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   269
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   270
    def load(self, repo):
3346
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   271
        """load data from disk"""
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   272
        assert repo.filtername is None
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   273
        self._cachekey = self.emptykey
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   274
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   275
        if self._con is not None:
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   276
            self._cachekey = (self._ondisktiprev, self._ondisktipnode)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   277
        self._ondiskkey = self._cachekey
3343
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   278
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   279
    def save(self, repo):
3346
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   280
        if self._cachekey is None or self._cachekey == self._ondiskkey:
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   281
            return
3343
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   282
        self._save(repo)
86a03229d32d stablerange: introduce a sql backed version of the generic on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3342
diff changeset
   283
3344
4d054737a79c stablerange: have a mergepoint based sql backed class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3343
diff changeset
   284
class mergepointsql(stablerangesql, stablerange.stablerange_mergepoint):
4d054737a79c stablerange: have a mergepoint based sql backed class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3343
diff changeset
   285
4d054737a79c stablerange: have a mergepoint based sql backed class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3343
diff changeset
   286
    _schemaversion = 2
4d054737a79c stablerange: have a mergepoint based sql backed class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3343
diff changeset
   287
    _cachefile = 'cache/evoext_stablerange_v2.sqlite'
3346
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   288
    _cachename = 'evo-ext-stablerange-mergepoint'
3344
4d054737a79c stablerange: have a mergepoint based sql backed class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3343
diff changeset
   289
3308
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   290
class sqlstablerange(stablerangesqlbase, stablerange.stablerange):
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   291
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   292
    _schemaversion = 1
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   293
    _cachefile = 'cache/evoext_stablerange_v1.sqlite'
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   294
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   295
    def warmup(self, repo, upto=None):
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   296
        self._con # make sure the data base is loaded
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   297
        try:
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   298
            # samelessly lock the repo to ensure nobody will update the repo
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   299
            # concurently. This should not be too much of an issue if we warm
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   300
            # at the end of the transaction.
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   301
            #
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   302
            # XXX However, we lock even if we are up to date so we should check
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   303
            # before locking
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   304
            with repo.lock():
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   305
                super(sqlstablerange, self).warmup(repo, upto)
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   306
                self._save(repo)
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   307
        except error.LockError:
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   308
            # Exceptionnally we are noisy about it since performance impact is
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   309
            # large We should address that before using this more widely.
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   310
            repo.ui.warn('stable-range cache: unable to lock repo while warming\n')
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   311
            repo.ui.warn('(cache will not be saved)\n')
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   312
            super(sqlstablerange, self).warmup(repo, upto)
65af5f9f232b stablerange: abstract the bit able to store cache into sql
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3307
diff changeset
   313
2125
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   314
@eh.reposetup
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   315
def setupcache(ui, repo):
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   316
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   317
    class stablerangerepo(repo.__class__):
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   318
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   319
        @localrepo.unfilteredpropertycache
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   320
        def stablerange(self):
3346
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   321
            cache = mergepointsql(repo)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   322
            cache.update(repo)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   323
            return cache
2125
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   324
2236
c0e2ba85e76a stablerange: drop the cache on 'destroyed'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2235
diff changeset
   325
        @localrepo.unfilteredmethod
c0e2ba85e76a stablerange: drop the cache on 'destroyed'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2235
diff changeset
   326
        def destroyed(self):
c0e2ba85e76a stablerange: drop the cache on 'destroyed'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2235
diff changeset
   327
            if 'stablerange' in vars(self):
3346
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   328
                self.stablerange.clear()
2236
c0e2ba85e76a stablerange: drop the cache on 'destroyed'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2235
diff changeset
   329
                del self.stablerange
2287
18b8dc058f75 repo: properly progate "destroyed" call to super class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2240
diff changeset
   330
            super(stablerangerepo, self).destroyed()
2236
c0e2ba85e76a stablerange: drop the cache on 'destroyed'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2235
diff changeset
   331
3346
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   332
        if util.safehasattr(repo, 'updatecaches'):
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   333
            @localrepo.unfilteredmethod
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   334
            def updatecaches(self, tr=None):
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   335
                if utility.shouldwarmcache(repo):
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   336
                    self.stablerange.update(repo)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   337
                    self.stablerange.save(repo)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   338
                super(stablerangerepo, self).updatecaches(tr)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   339
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   340
        else:
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   341
            def transaction(self, *args, **kwargs):
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   342
                tr = super(stablerangerepo, self).transaction(*args, **kwargs)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   343
                reporef = weakref.ref(self)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   344
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   345
                def _warmcache(tr):
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   346
                    repo = reporef()
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   347
                    if repo is None:
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   348
                        return
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   349
                    repo = repo.unfiltered()
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   350
                    repo.stablerange.update(repo)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   351
                    repo.stablerange.save(repo)
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   352
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   353
                if utility.shouldwarmcache(repo):
f4e28b781143 stablerange: use mergepoint based algorithm for the official stable range
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 3344
diff changeset
   354
                    tr.addpostclose('warmcache-10stablerange', _warmcache)
2551
ecd47c63b6de obshashrange: add an option to protect from accidental activation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2529
diff changeset
   355
                return tr
2238
aac765e84de3 stablerange: warm cache on transaction (if obshashrange is enabled)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 2237
diff changeset
   356
2125
e0a25339ff17 stablerange: move 'depth' inside a new 'stablerange' module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   357
    repo.__class__ = stablerangerepo