# HG changeset patch # User Jun Wu <qu...@fb.com> # Date 1496558287 25200 # Sat Jun 03 23:38:07 2017 -0700 # Node ID 69870e8f6bc97775c47d363efc5c58bce33239c0 # Parent 994e09024cdd5bbca80f1beb9dcbd2f1a19aa1bb # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 69870e8f6bc9 obsstore: generalize successors, precursors, children to a class
Add a "markerindex" class which takes a function to extract key from a marker. Therefore "successors", "precursors", "children" can reuse the same implementation by specifying different "keyfunc"s. There is no noticeable perf change running "hg log -r ." in hg-committed. I guess subclassing builtin dict is the key to gain good perf. Note the "dict" base class is temporary and will be changed in a later patch. diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py --- a/mercurial/obsolete.py +++ b/mercurial/obsolete.py @@ -72,4 +72,5 @@ from __future__ import absolute_import import errno import struct +import weakref from .i18n import _ @@ -507,22 +508,26 @@ class marker(object): return self._data[2] -@util.nogc -def _addsuccessors(successors, markers): - for mark in markers: - successors.setdefault(mark[0], set()).add(mark) +class markerindex(dict): + """key is usually a node, value is a set of markers""" + + def __init__(self, obsstore, name, keyfunc): + """keyfunc: rawmarker -> [key]""" + self._keyfunc = keyfunc + self._obsstore = weakref.proxy(obsstore) + self.name = name + self.sourceoftruthsize = 0 + self.update() -@util.nogc -def _addprecursors(precursors, markers): - for mark in markers: - for suc in mark[1]: - precursors.setdefault(suc, set()).add(mark) - -@util.nogc -def _addchildren(children, markers): - for mark in markers: - parents = mark[5] - if parents is not None: - for p in parents: - children.setdefault(p, set()).add(mark) + @util.nogc + def update(self): + """read latest obsstore and build index for its markers""" + allmarkers = self._obsstore._all + keyfunc = self._keyfunc + setdefault = self.setdefault + for i in xrange(self.sourceoftruthsize, len(allmarkers)): + marker = allmarkers[i] + for k in keyfunc(marker): + setdefault(k, set()).add(marker) + self.sourceoftruthsize = len(allmarkers) def _checkinvalidmarkers(markers): @@ -693,19 +698,13 @@ class obsstore(object): @propertycache def successors(self): - successors = {} - _addsuccessors(successors, self._all) - return successors + return markerindex(self, 'successors', lambda m: (m[0],)) @propertycache def precursors(self): - precursors = {} - _addprecursors(precursors, self._all) - return precursors + return markerindex(self, 'precursors', lambda m: m[1]) @propertycache def children(self): - children = {} - _addchildren(children, self._all) - return children + return markerindex(self, 'children', lambda m: m[5] or ()) def _cached(self, attr): @@ -716,10 +715,8 @@ class obsstore(object): self._data = self._data + rawdata self._all.extend(markers) - if self._cached('successors'): - _addsuccessors(self.successors, markers) - if self._cached('precursors'): - _addprecursors(self.precursors, markers) - if self._cached('children'): - _addchildren(self.children, markers) + for name in ('successors', 'precursors', 'children'): + index = self.__dict__.get(name, None) + if index is not None: + index.update() _checkinvalidmarkers(markers) _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel