# HG changeset patch # User Pierre-Yves David # Date 1493840826 -7200 # Node ID 7ccacaa387824a965151e99a4a5d8bf6916959e3 # Parent 6b751daad348b350776635e34d841e37081f4753 obscache: Only access the new obsmarkers for marker update Since we know what what is the part of the file with "new" markers we can just access these. If the cache was up to date before the transaction, we'll re-parse data we just wrote. See the inline comment for details. This is good enough for now. diff --git a/hgext3rd/evolve/obscache.py b/hgext3rd/evolve/obscache.py --- a/hgext3rd/evolve/obscache.py +++ b/hgext3rd/evolve/obscache.py @@ -13,6 +13,7 @@ import errno from mercurial import ( + error, localrepo, obsolete, phases, @@ -20,6 +21,8 @@ util, ) +from mercurial.i18n import _ + from . import ( exthelper, ) @@ -160,6 +163,31 @@ return True, startrev, startidx + +# XXX copied as is from Mercurial 4.2 and added the "offset" parameters +@util.nogc +def _readmarkers(data, offset=None): + """Read and enumerate markers from raw data""" + off = 0 + diskversion = struct.unpack('>B', data[off:off + 1])[0] + if offset is None: + off += 1 + else: + assert 1 <= offset + off = offset + if diskversion not in obsolete.formats: + raise error.Abort(_('parsing obsolete marker: unknown version %r') + % diskversion) + return diskversion, obsolete.formats[diskversion][0](data, off) + +def markersfrom(obsstore, byteoffset, firstmarker): + if '_all' in vars(obsstore): + # if the data are in memory, just use that + return obsstore._all[firstmarker:] + else: + obsdata = obsstore.svfs.tryread('obsstore') + return _readmarkers(obsdata, byteoffset)[1] + class obscache(object): """cache the "does a rev" is the precursors of some obsmarkers data @@ -258,23 +286,10 @@ # process the new obsmarkers if startidx is not None: - markers = repo.obsstore._all - # Note: - # - # There are no actually needs to load the full obsstore here, - # since we only read the latest ones. We do it for simplicity in - # the first implementation. Loading the full obsstore has a - # performance cost and should go away in this case too. We have - # two simples options for that: - # - # 1) provide and API to start reading markers from a byte offset - # (we have that data in the cache key) - # - # 2) directly update the cache at a lower level, in the code - # responsible for adding a markers. - # - # Option 2 is probably a bit more invasive, but more solid on the long run - markers = [markers[i] for i in xrange(startidx, len(repo.obsstore))] + if startidx == 0: # all markers + markers = repo.obsstore._all + else: + markers = markersfrom(repo.obsstore, self._cachekey[3], startidx) self._updatemarkers(repo, markers) self._cachekey = getcachekey(repo)