obsolete: populate successors, precursors, children lazily
The precursors and children dictionaries are not used by many
commands. By making them lazily populated,
'hg log -r @~10::@ >/dev/null' is sped up from 0.564s to 0.440s on my
hg.hg repo with 73k markers.
Also make successors lazily populated, mostly for consistency with the
others.
--- a/mercurial/obsolete.py Wed Feb 04 22:40:48 2015 -0800
+++ b/mercurial/obsolete.py Wed Feb 04 22:25:35 2015 -0800
@@ -75,6 +75,7 @@
_pack = struct.pack
_unpack = struct.unpack
_calcsize = struct.calcsize
+propertycache = util.propertycache
_SEEK_END = 2 # os.SEEK_END was introduced in Python 2.5
@@ -522,16 +523,13 @@
# caches for various obsolescence related cache
self.caches = {}
self._all = []
- self.precursors = {}
- self.successors = {}
- self.children = {}
self.sopener = sopener
data = sopener.tryread('obsstore')
self._version = defaultformat
self._readonly = readonly
if data:
self._version, markers = _readmarkers(data)
- self._load(markers)
+ self._addmarkers(markers)
def __iter__(self):
return iter(self._all)
@@ -609,7 +607,7 @@
# XXX: f.close() == filecache invalidation == obsstore rebuilt.
# call 'filecacheentry.refresh()' here
f.close()
- self._load(new)
+ self._addmarkers(new)
# new marker *may* have changed several set. invalidate the cache.
self.caches.clear()
# records the number of new markers for the transaction hooks
@@ -624,12 +622,36 @@
version, markers = _readmarkers(data)
return self.add(transaction, markers)
- def _load(self, markers):
+ @propertycache
+ def successors(self):
+ successors = {}
+ _addsuccessors(successors, self._all)
+ return successors
+
+ @propertycache
+ def precursors(self):
+ precursors = {}
+ _addprecursors(precursors, self._all)
+ return precursors
+
+ @propertycache
+ def children(self):
+ children = {}
+ _addchildren(children, self._all)
+ return children
+
+ def _cached(self, attr):
+ return attr in self.__dict__
+
+ def _addmarkers(self, markers):
markers = list(markers) # to allow repeated iteration
self._all.extend(markers)
- _addsuccessors(self.successors, markers)
- _addprecursors(self.precursors, markers)
- _addchildren(self.children, 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)
_checkinvalidmarkers(markers)
def relevantmarkers(self, nodes):