obscache: shortcut the attribute access for testing
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 05 Jun 2017 10:21:38 +0100
changeset 2552 006400e25e22
parent 2543 3e62042a6bb7
child 2553 85cabd631a1b
obscache: shortcut the attribute access for testing The attribute access adds a significant overhead. we can gain -20% performance by doing so.
hgext3rd/evolve/obscache.py
--- a/hgext3rd/evolve/obscache.py	Thu Jun 01 03:35:45 2017 +0200
+++ b/hgext3rd/evolve/obscache.py	Mon Jun 05 10:21:38 2017 +0100
@@ -364,18 +364,31 @@
         super(obscache, self).__init__()
         self._ondiskkey = None
         self._vfs = repo.vfs
-        self._data = bytearray()
+        self._setdata(bytearray())
+
+    @util.propertycache
+    def get(self):
+        """final signature: obscache.get(rev)
+
+        return True if "rev" is used as "precursors for any obsmarkers
 
-    def get(self, rev):
-        """return True if "rev" is used as "precursors for any obsmarkers
+        IMPORTANT: make sure the cache has been updated to match the repository
+        content before using it
 
-        Make sure the cache has been updated to match the repository content before using it"""
-        return self._data[rev]
+        We use a property cache to skip the attribute resolution overhead in
+        hot loops."""
+        return self._data.__getitem__
+
+    def _setdata(self, data):
+        """set a new bytearray data, invalidating the 'get' shortcut if needed"""
+        self._data = data
+        if 'get' in vars(self):
+            del self.get
 
     def clear(self, reset=False):
         """invalidate the cache content"""
         super(obscache, self).clear(reset=reset)
-        self._data = bytearray()
+        self._setdata(bytearray())
 
     def _updatefrom(self, repo, revs, obsmarkers):
         if revs:
@@ -443,11 +456,11 @@
         data = repo.vfs.tryread(self._filepath)
         if not data:
             self._cachekey = self.emptykey
-            self._data = bytearray()
+            self._setdata(bytearray())
         else:
             headersize = struct.calcsize(self._headerformat)
             self._cachekey = struct.unpack(self._headerformat, data[:headersize])
-            self._data = bytearray(data[headersize:])
+            self._setdata(bytearray(data[headersize:]))
         self._ondiskkey = self._cachekey
 
 def _computeobsoleteset(orig, repo):