[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

eric at webkit.org eric at webkit.org
Wed Dec 22 15:07:30 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 8baf0e9883461a252517e8e4f935db70634254e8
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 28 05:12:39 2010 +0000

    2010-10-27  Eric Seidel  <eric at webkit.org>
    
            Reviewed by Adam Barth.
    
            webkit-patch suggest-reviewers -g 260550a6e30b7bf34f16bdb4a5396cf26264fc1c is very slow
            https://bugs.webkit.org/show_bug.cgi?id=48500
    
            This doesn't fix the problem, but it makes things slightly better.
            Each git svn find-rev call takes about .25 seconds on my desktop.
            This patch uses a new memoized class to avoid those calls when possible.
    
            The real slowness is still git log on some files, like:
            git log --pretty=format:%H -5 -- /Projects/WebKit/WebCore/platform/wx/SearchPopupMenuWx.h
            I'm not yet sure how to make the pathological git logs better.
    
            * Scripts/webkitpy/common/checkout/scm.py:
            * Scripts/webkitpy/common/memoized.py: Added.
            * Scripts/webkitpy/common/memoized_unittest.py: Added.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70747 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index e67217a..2f02899 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,5 +1,24 @@
 2010-10-27  Eric Seidel  <eric at webkit.org>
 
+        Reviewed by Adam Barth.
+
+        webkit-patch suggest-reviewers -g 260550a6e30b7bf34f16bdb4a5396cf26264fc1c is very slow
+        https://bugs.webkit.org/show_bug.cgi?id=48500
+
+        This doesn't fix the problem, but it makes things slightly better.
+        Each git svn find-rev call takes about .25 seconds on my desktop.
+        This patch uses a new memoized class to avoid those calls when possible.
+
+        The real slowness is still git log on some files, like:
+        git log --pretty=format:%H -5 -- /Projects/WebKit/WebCore/platform/wx/SearchPopupMenuWx.h
+        I'm not yet sure how to make the pathological git logs better.
+
+        * Scripts/webkitpy/common/checkout/scm.py:
+        * Scripts/webkitpy/common/memoized.py: Added.
+        * Scripts/webkitpy/common/memoized_unittest.py: Added.
+
+2010-10-27  Eric Seidel  <eric at webkit.org>
+
         Reviewed by Ojan Vafai.
 
         EWS bots should not use --quiet when running build-webkit
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
index 7e3ad4d..fb3c5a7 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
@@ -36,6 +36,7 @@ import shutil
 
 from webkitpy.common.system.executive import Executive, run_command, ScriptError
 from webkitpy.common.system.deprecated_logging import error, log
+from webkitpy.common.memoized import memoized
 
 
 def find_checkout_root():
@@ -319,7 +320,6 @@ class SVN(SCM):
 
     def __init__(self, cwd):
         SCM.__init__(self, cwd)
-        self.cached_version = None
         self._bogus_dir = None
 
     @staticmethod
@@ -369,11 +369,9 @@ class SVN(SCM):
         find_output = self.run(find_args, cwd=home_directory, error_handler=Executive.ignore_error).rstrip()
         return find_output and os.path.isfile(os.path.join(home_directory, find_output))
 
+    @memoized
     def svn_version(self):
-        if not self.cached_version:
-            self.cached_version = self.run(['svn', '--version', '--quiet'])
-        
-        return self.cached_version
+        return self.run(['svn', '--version', '--quiet'])
 
     def working_directory_is_clean(self):
         return self.run(["svn", "diff"], cwd=self.checkout_root, decode_output=False) == ""
@@ -572,6 +570,7 @@ class SVN(SCM):
         dir, base = os.path.split(path)
         return self.run(['svn', 'pget', pname, base], cwd=dir).encode('utf-8').rstrip("\n")
 
+
 # All git-specific logic should go here.
 class Git(SCM):
     def __init__(self, cwd):
@@ -703,21 +702,29 @@ class Git(SCM):
         # FIXME: This should probably use cwd=self.checkout_root
         return self.run(['git', 'diff', '--binary', "--no-ext-diff", "--full-index", "-M", self.merge_base(git_commit), "--"] + changed_files, decode_output=False)
 
-    @classmethod
-    def git_commit_from_svn_revision(cls, revision):
-        # FIXME: This should probably use cwd=self.checkout_root
-        git_commit = run_command(['git', 'svn', 'find-rev', 'r%s' % revision]).rstrip()
-        # git svn find-rev always exits 0, even when the revision is not found.
-        if not git_commit:
-            raise ScriptError(message='Failed to find git commit for revision %s, your checkout likely needs an update.' % revision)
-        return git_commit
+    def _run_git_svn_find_rev(self, arg):
+        # git svn find-rev always exits 0, even when the revision or commit is not found.
+        return self.run(['git', 'svn', 'find-rev', arg], cwd=self.checkout_root).rstrip()
 
-    def svn_revision_from_git_commit(self, commit_id):
+    def _string_to_int_or_none(self, string):
         try:
-            return int(self.run(['git', 'svn', 'find-rev', commit_id]).rstrip())
+            return int(string)
         except ValueError, e:
             return None
 
+    @memoized
+    def git_commit_from_svn_revision(self, svn_revision):
+        git_commit = self._run_git_svn_find_rev('r%s' % svn_revision)
+        if not git_commit:
+            # FIXME: Alternatively we could offer to update the checkout? Or return None?
+            raise ScriptError(message='Failed to find git commit for revision %s, your checkout likely needs an update.' % svn_revision)
+        return git_commit
+
+    @memoized
+    def svn_revision_from_git_commit(self, git_commit):
+        svn_revision = self._run_git_svn_find_rev(git_commit)
+        return self._string_to_int_or_none(svn_revision)
+
     def contents_at_revision(self, path, revision):
         """Returns a byte array (str()) containing the contents
         of path @ revision in the repository."""
diff --git a/WebKitTools/Scripts/webkitpy/common/memoized.py b/WebKitTools/Scripts/webkitpy/common/memoized.py
new file mode 100644
index 0000000..dc844a5
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/memoized.py
@@ -0,0 +1,55 @@
+# Copyright (c) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Python does not (yet) seem to provide automatic memoization.  So we've
+# written a small decorator to do so.
+
+import functools
+
+
+class memoized(object):
+    def __init__(self, function):
+        self._function = function
+        self._results_cache = {}
+
+    def __call__(self, *args):
+        try:
+            return self._results_cache[args]
+        except KeyError:
+            # If we didn't find the args in our cache, call and save the results.
+            result = self._function(*args)
+            self._results_cache[args] = result
+            return result
+        # FIXME: We may need to handle TypeError here in the case
+        # that "args" is not a valid dictionary key.
+
+    # Use python "descriptor" protocol __get__ to appear
+    # invisible during property access.
+    def __get__(self, instance, owner):
+        # Return a function partial with obj already bound as self.
+        return functools.partial(self.__call__, instance)
diff --git a/WebKitTools/Scripts/webkitpy/common/memoized_unittest.py b/WebKitTools/Scripts/webkitpy/common/memoized_unittest.py
new file mode 100644
index 0000000..dd7c793
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/memoized_unittest.py
@@ -0,0 +1,65 @@
+# Copyright (c) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+
+from webkitpy.common.memoized import memoized
+
+
+class _TestObject(object):
+    def __init__(self):
+        self.callCount = 0
+
+    @memoized
+    def memoized_add(self, argument):
+        """testing docstring"""
+        self.callCount += 1
+        if argument is None:
+            return None  # Avoid the TypeError from None + 1
+        return argument + 1
+
+
+class MemoizedTest(unittest.TestCase):
+    def test_caching(self):
+        test = _TestObject()
+        test.callCount = 0
+        self.assertEqual(test.memoized_add(1), 2)
+        self.assertEqual(test.callCount, 1)
+        self.assertEqual(test.memoized_add(1), 2)
+        self.assertEqual(test.callCount, 1)
+
+        # Validate that callCount is working as expected.
+        self.assertEqual(test.memoized_add(2), 3)
+        self.assertEqual(test.callCount, 2)
+
+    def test_tearoff(self):
+        test = _TestObject()
+        # Make sure that get()/tear-offs work:
+        tearoff = test.memoized_add
+        self.assertEqual(tearoff(4), 5)
+        self.assertEqual(test.callCount, 1)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list