Code

Merge branch 'ag/rewrite_one' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 7 Aug 2008 01:48:32 +0000 (18:48 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Aug 2008 18:40:12 +0000 (11:40 -0700)
* ag/rewrite_one:
  Fix quadratic performance in rewrite_one.

1  2 
revision.c

diff --combined revision.c
index 8dc3ca7bf696c14ad73f4ebe0fe845cba298c20e,d464f14d500500b22fea74723a0fe69819f2adc7..a68abec3f203d751db3eb4bce9c8e958abf3cc9e
@@@ -259,7 -259,7 +259,7 @@@ static int tree_difference = REV_TREE_S
  static void file_add_remove(struct diff_options *options,
                    int addremove, unsigned mode,
                    const unsigned char *sha1,
 -                  const char *base, const char *path)
 +                  const char *fullpath)
  {
        int diff = REV_TREE_DIFFERENT;
  
@@@ -285,7 -285,7 +285,7 @@@ static void file_change(struct diff_opt
                 unsigned old_mode, unsigned new_mode,
                 const unsigned char *old_sha1,
                 const unsigned char *new_sha1,
 -               const char *base, const char *path)
 +               const char *fullpath)
  {
        tree_difference = REV_TREE_DIFFERENT;
        DIFF_OPT_SET(options, HAS_CHANGES);
@@@ -412,10 -412,26 +412,26 @@@ static void try_to_simplify_commit(stru
        commit->object.flags |= TREESAME;
  }
  
- static int add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)
+ static void insert_by_date_cached(struct commit *p, struct commit_list **head,
+                   struct commit_list *cached_base, struct commit_list **cache)
+ {
+       struct commit_list *new_entry;
+       if (cached_base && p->date < cached_base->item->date)
+               new_entry = insert_by_date(p, &cached_base->next);
+       else
+               new_entry = insert_by_date(p, head);
+       if (cache && (!*cache || p->date < (*cache)->item->date))
+               *cache = new_entry;
+ }
+ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
+                   struct commit_list **list, struct commit_list **cache_ptr)
  {
        struct commit_list *parent = commit->parents;
        unsigned left_flag;
+       struct commit_list *cached_base = cache_ptr ? *cache_ptr : NULL;
  
        if (commit->object.flags & ADDED)
                return 0;
                        if (p->object.flags & SEEN)
                                continue;
                        p->object.flags |= SEEN;
-                       insert_by_date(p, list);
+                       insert_by_date_cached(p, list, cached_base, cache_ptr);
                }
                return 0;
        }
                p->object.flags |= left_flag;
                if (!(p->object.flags & SEEN)) {
                        p->object.flags |= SEEN;
-                       insert_by_date(p, list);
+                       insert_by_date_cached(p, list, cached_base, cache_ptr);
                }
                if(revs->first_parent_only)
                        break;
@@@ -611,7 -627,7 +627,7 @@@ static int limit_list(struct rev_info *
  
                if (revs->max_age != -1 && (commit->date < revs->max_age))
                        obj->flags |= UNINTERESTING;
-               if (add_parents_to_list(revs, commit, &list) < 0)
+               if (add_parents_to_list(revs, commit, &list, NULL) < 0)
                        return -1;
                if (obj->flags & UNINTERESTING) {
                        mark_parents_uninteresting(commit);
@@@ -1458,10 -1474,12 +1474,12 @@@ enum rewrite_result 
  
  static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp)
  {
+       struct commit_list *cache = NULL;
        for (;;) {
                struct commit *p = *pp;
                if (!revs->limited)
-                       if (add_parents_to_list(revs, p, &revs->commits) < 0)
+                       if (add_parents_to_list(revs, p, &revs->commits, &cache) < 0)
                                return rewrite_one_error;
                if (p->parents && p->parents->next)
                        return rewrite_one_ok;
@@@ -1580,7 -1598,7 +1598,7 @@@ static struct commit *get_revision_1(st
                        if (revs->max_age != -1 &&
                            (commit->date < revs->max_age))
                                continue;
-                       if (add_parents_to_list(revs, commit, &revs->commits) < 0)
+                       if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0)
                                return NULL;
                }