diff options
author | Junio C Hamano <junkio@cox.net> | 2006-10-31 01:00:01 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-10-31 01:00:01 -0800 |
commit | 0d981c67d8bcf4610e165744059c1e9e14609baa (patch) | |
tree | 410320bb548cf1825f2f92fa9886b736d354fa65 | |
parent | f69e743d97cdb3f6647ea0620a22311e7bf36051 (diff) | |
download | git-0d981c67d8bcf4610e165744059c1e9e14609baa.tar.gz git-0d981c67d8bcf4610e165744059c1e9e14609baa.tar.xz |
git-pickaxe: cache one already found path per commit.
Depending on how bushy the commit DAG is, this saves calls to
the internal diff-tree for fork-point commits. For example,
annotating Makefile in the kernel repository saves about a third
of such diff-tree calls.
Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r-- | builtin-pickaxe.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/builtin-pickaxe.c b/builtin-pickaxe.c index 32dc3932e..c9405e918 100644 --- a/builtin-pickaxe.c +++ b/builtin-pickaxe.c @@ -141,6 +141,8 @@ static int cmp_suspect(struct origin *a, struct origin *b) return strcmp(a->path, b->path); } +#define cmp_suspect(a, b) ( ((a)==(b)) ? 0 : cmp_suspect(a,b) ) + static void sanity_check_refcnt(struct scoreboard *); static void coalesce(struct scoreboard *sb) @@ -213,6 +215,12 @@ static struct origin *find_origin(struct scoreboard *sb, struct diff_options diff_opts; const char *paths[2]; + if (parent->util) { + struct origin *cached = parent->util; + if (!strcmp(cached->path, origin->path)) + return origin_incref(cached); + } + /* See if the origin->path is different between parent * and origin first. Most of the time they are the * same and diff-tree is fairly efficient about this. @@ -259,6 +267,12 @@ static struct origin *find_origin(struct scoreboard *sb, } } diff_flush(&diff_opts); + if (porigin) { + origin_incref(porigin); + if (parent->util) + origin_decref(parent->util); + parent->util = porigin; + } return porigin; } @@ -905,7 +919,7 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt) continue; if (parse_commit(p)) continue; - porigin = find(sb, parent->item, origin); + porigin = find(sb, p, origin); if (!porigin) continue; if (!hashcmp(porigin->blob_sha1, origin->blob_sha1)) { @@ -1371,8 +1385,10 @@ static void sanity_check_refcnt(struct scoreboard *sb) ent->suspect->refcnt = -ent->suspect->refcnt; } for (ent = sb->ent; ent; ent = ent->next) { - /* then pick each and see if they have the the - * correct refcnt + /* then pick each and see if they have the the correct + * refcnt; note that ->util caching means origin's refcnt + * may well be greater than the number of blame entries + * that use it. */ int found; struct blame_entry *e; @@ -1386,7 +1402,7 @@ static void sanity_check_refcnt(struct scoreboard *sb) continue; found++; } - if (suspect->refcnt != found) + if (suspect->refcnt < found) baa = 1; } if (baa) { |