diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2012-01-14 19:19:53 +0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-01-16 14:27:24 -0800 |
commit | 941ba8db57f2d075aee48b002ee30686288cb502 (patch) | |
tree | 799a3cb140b3ca13c8d64d8e5a6c2d6c89ad0c35 /commit.c | |
parent | ec330158ec04849fe5ff2cb8749797cd63ae592b (diff) | |
download | git-941ba8db57f2d075aee48b002ee30686288cb502.tar.gz git-941ba8db57f2d075aee48b002ee30686288cb502.tar.xz |
Eliminate recursion in setting/clearing marks in commit list
Recursion in a DAG is generally a bad idea because it could be very
deep. Be defensive and avoid recursion in mark_parents_uninteresting()
and clear_commit_marks().
mark_parents_uninteresting() learns a trick from clear_commit_marks()
to avoid malloc() in (dominant) single-parent case.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'commit.c')
-rw-r--r-- | commit.c | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -421,7 +421,8 @@ struct commit *pop_most_recent_commit(struct commit_list **list, return ret; } -void clear_commit_marks(struct commit *commit, unsigned int mark) +static void clear_commit_marks_1(struct commit_list **plist, + struct commit *commit, unsigned int mark) { while (commit) { struct commit_list *parents; @@ -436,12 +437,20 @@ void clear_commit_marks(struct commit *commit, unsigned int mark) return; while ((parents = parents->next)) - clear_commit_marks(parents->item, mark); + commit_list_insert(parents->item, plist); commit = commit->parents->item; } } +void clear_commit_marks(struct commit *commit, unsigned int mark) +{ + struct commit_list *list = NULL; + commit_list_insert(commit, &list); + while (list) + clear_commit_marks_1(&list, pop_commit(&list), mark); +} + void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark) { struct object *object; |