stablerange: abstract the bit able to store cache into sql
The part about actually storing the range is independent of the algorithm, so we
should extract this before using it for the next iteration.
--- a/hgext3rd/evolve/stablerangecache.py Mon Dec 18 00:40:07 2017 +0100
+++ b/hgext3rd/evolve/stablerangecache.py Mon Dec 18 01:53:20 2017 +0100
@@ -1,3 +1,4 @@
+import abc
import sqlite3
import weakref
@@ -54,41 +55,27 @@
WHERE (suprev = ? AND supidx = ?)
ORDER BY listidx;"""
-class sqlstablerange(stablerange.stablerange):
+class stablerangesqlbase(stablerange.stablerangecached):
+ """class that can handle all the bits needed to store range into sql
+ """
- _schemaversion = 1
+ __metaclass__ = abc.ABCMeta
- def __init__(self, repo):
- lrusize = repo.ui.configint('experimental', 'obshashrange.lru-size',
- 2000)
- super(sqlstablerange, self).__init__(lrusize=lrusize)
+ _schemaversion = None
+ _cachefile = None
+
+ def __init__(self, repo, **kwargs):
+ super(stablerangesqlbase, self).__init__(**kwargs)
self._vfs = repo.vfs
- self._path = repo.vfs.join('cache/evoext_stablerange_v1.sqlite')
+ self._path = repo.vfs.join(self._cachefile)
self._cl = repo.unfiltered().changelog # (okay to keep an old one)
self._ondisktiprev = None
self._ondisktipnode = None
self._unsavedsubranges = {}
- def warmup(self, repo, upto=None):
- self._con # make sure the data base is loaded
- try:
- # samelessly lock the repo to ensure nobody will update the repo
- # concurently. This should not be too much of an issue if we warm
- # at the end of the transaction.
- #
- # XXX However, we lock even if we are up to date so we should check
- # before locking
- with repo.lock():
- super(sqlstablerange, self).warmup(repo, upto)
- self._save(repo)
- except error.LockError:
- # Exceptionnally we are noisy about it since performance impact is
- # large We should address that before using this more widely.
- repo.ui.warn('stable-range cache: unable to lock repo while warming\n')
- repo.ui.warn('(cache will not be saved)\n')
- super(sqlstablerange, self).warmup(repo, upto)
-
def _getsub(self, rangeid):
+ # 1) check the in memory cache
+ # 2) check the sqlcaches (and warm in memory cache we want we find)
cache = self._subrangescache
if rangeid not in cache and rangeid[0] <= self._ondisktiprev and self._con is not None:
value = None
@@ -102,7 +89,7 @@
def _setsub(self, rangeid, value):
assert rangeid not in self._unsavedsubranges
self._unsavedsubranges[rangeid] = value
- super(sqlstablerange, self)._setsub(rangeid, value)
+ super(stablerangesqlbase, self)._setsub(rangeid, value)
def _db(self):
try:
@@ -197,6 +184,30 @@
con.executemany(_updaterange, allranges)
con.executemany(_updatesubranges, data)
+class sqlstablerange(stablerangesqlbase, stablerange.stablerange):
+
+ _schemaversion = 1
+ _cachefile = 'cache/evoext_stablerange_v1.sqlite'
+
+ def warmup(self, repo, upto=None):
+ self._con # make sure the data base is loaded
+ try:
+ # samelessly lock the repo to ensure nobody will update the repo
+ # concurently. This should not be too much of an issue if we warm
+ # at the end of the transaction.
+ #
+ # XXX However, we lock even if we are up to date so we should check
+ # before locking
+ with repo.lock():
+ super(sqlstablerange, self).warmup(repo, upto)
+ self._save(repo)
+ except error.LockError:
+ # Exceptionnally we are noisy about it since performance impact is
+ # large We should address that before using this more widely.
+ repo.ui.warn('stable-range cache: unable to lock repo while warming\n')
+ repo.ui.warn('(cache will not be saved)\n')
+ super(sqlstablerange, self).warmup(repo, upto)
+
@eh.reposetup
def setupcache(ui, repo):