All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Karl Hasselström" <kha@treskal.com>
To: Catalin Marinas <catalin.marinas@gmail.com>
Cc: git@vger.kernel.org
Subject: [StGit PATCH 2/2] Reuse the same temp index in a transaction
Date: Wed, 02 Jul 2008 08:13:15 +0200	[thread overview]
Message-ID: <20080702061314.11361.28297.stgit@yoghurt> (raw)
In-Reply-To: <20080702060113.11361.39006.stgit@yoghurt>

Instead of making a new temp index every time we need one, just keep
reusing the same one. And keep track of which tree is currently stored
in it -- if we do several consecutive successful pushes, it's always
going to be the "right" tree so that we don't have to call read-tree
before each patch application.

The motivation behind this change is of course that it makes things
faster.

(The same simple test as in the previous patch -- pushing 250 patches
in a 32k-file repository, with one file-level merge necessary per push
-- went from 0.36 to 0.19 seconds per patch with this patch applied.)

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

 stgit/lib/git.py         |   43 +++++++++++++++++++++++++++++--------------
 stgit/lib/transaction.py |   12 +++++++++++-
 2 files changed, 40 insertions(+), 15 deletions(-)


diff --git a/stgit/lib/git.py b/stgit/lib/git.py
index a38eaa5..c98e919 100644
--- a/stgit/lib/git.py
+++ b/stgit/lib/git.py
@@ -459,31 +459,46 @@ class Repository(RunWithEnv):
     def set_head_ref(self, ref, msg):
         self.run(['git', 'symbolic-ref', '-m', msg, 'HEAD', ref]).no_output()
     def simple_merge(self, base, ours, theirs):
+        index = self.temp_index()
+        try:
+            result, index_tree = self.index_merge(base, ours, theirs,
+                                                  index, None)
+        finally:
+            index.delete()
+        return result
+    def index_merge(self, base, ours, theirs, index, current):
         """Given three L{Tree}s, tries to do an in-index merge with a
-        temporary index. Returns the result L{Tree}, or None if the
-        merge failed (due to conflicts)."""
+        temporary index. Returns a pair: the result L{Tree}, or None
+        if the merge failed (due to conflicts); and the L{Tree} now
+        stored in the index.
+
+        C{index} is the L{Index} object to use for the merge.
+        C{current} is the L{Tree} object currently stored in the given
+        index. If this is the same as C{ours}, some work is saved.
+        (C{current} may be C{None}, in which case this optimization is
+        disabled.)"""
         assert isinstance(base, Tree)
         assert isinstance(ours, Tree)
         assert isinstance(theirs, Tree)
+        assert isinstance(index, Index)
+        assert current == None or isinstance(current, Tree)
 
         # Take care of the really trivial cases.
         if base == ours:
-            return theirs
+            return (theirs, current)
         if base == theirs:
-            return ours
+            return (ours, current)
         if ours == theirs:
-            return ours
+            return (ours, current)
 
-        index = self.temp_index()
-        index.read_tree(ours)
+        if current != ours:
+            index.read_tree(ours)
         try:
-            try:
-                index.apply_treediff(base, theirs)
-                return index.write_tree()
-            except MergeException:
-                return None
-        finally:
-            index.delete()
+            index.apply_treediff(base, theirs)
+            result = index.write_tree()
+            return result, result
+        except MergeException:
+            return None, ours
     def apply(self, tree, patch_text):
         """Given a L{Tree} and a patch, will either return the new L{Tree}
         that results when the patch is applied, or None if the patch
diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index e47997e..b4d4b75 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -1,6 +1,8 @@
 """The L{StackTransaction} class makes it possible to make complex
 updates to an StGit stack in a safe and convenient way."""
 
+import atexit
+
 from stgit import exception, utils
 from stgit.utils import any, all
 from stgit.out import *
@@ -84,6 +86,7 @@ class StackTransaction(object):
             self.__allow_conflicts = lambda trans: allow_conflicts
         else:
             self.__allow_conflicts = allow_conflicts
+        self.__temp_index = self.temp_index_tree = None
     stack = property(lambda self: self.__stack)
     patches = property(lambda self: self.__patches)
     def __set_applied(self, val):
@@ -97,6 +100,12 @@ class StackTransaction(object):
                 or self.patches[self.applied[0]].data.parent == val)
         self.__base = val
     base = property(lambda self: self.__base, __set_base)
+    @property
+    def temp_index(self):
+        if not self.__temp_index:
+            self.__temp_index = self.__stack.repository.temp_index()
+            atexit.register(self.__temp_index.delete)
+        return self.__temp_index
     def __checkout(self, tree, iw):
         if not self.__stack.head_top_equal():
             out.error(
@@ -238,7 +247,8 @@ class StackTransaction(object):
         base = oldparent.data.tree
         ours = cd.parent.data.tree
         theirs = cd.tree
-        tree = self.__stack.repository.simple_merge(base, ours, theirs)
+        tree, self.temp_index_tree = self.__stack.repository.index_merge(
+            base, ours, theirs, self.temp_index, self.temp_index_tree)
         merge_conflict = False
         if not tree:
             if iw == None:

  parent reply	other threads:[~2008-07-02  6:21 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-02  6:12 [StGit PATCH 0/2] push optimizations Karl Hasselström
2008-07-02  6:12 ` [StGit PATCH 1/2] Do simple in-index merge with diff+apply instead of read-tree Karl Hasselström
2008-07-12 10:22   ` Catalin Marinas
2008-07-02  6:13 ` Karl Hasselström [this message]
2008-07-03 21:38   ` [StGit PATCH v2] Reuse the same temp index in a transaction Karl Hasselström
2008-07-12 10:24   ` [StGit PATCH 2/2] " Catalin Marinas
2008-07-14  6:35     ` Karl Hasselström
2008-07-07 21:12 ` [StGit PATCH 0/2] push optimizations Catalin Marinas
2008-07-08  4:36   ` Karl Hasselström

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080702061314.11361.28297.stgit@yoghurt \
    --to=kha@treskal.com \
    --cc=catalin.marinas@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.