2 * This file is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2,
4 * as published by the Free Software Foundation.
6 * In addition to the permissions in the GNU General Public License,
7 * the authors give you unlimited permission to link the compiled
8 * version of this file into combinations with other programs,
9 * and to distribute those combinations without any restriction
10 * coming from the use of this file. (The General Public License
11 * restrictions do apply in other respects; for example, they cover
12 * modification of the file, and distribution when not linked into
13 * a combined executable.)
15 * This file is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; see the file COPYING. If not, write to
22 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
30 static const int default_table_size
= 32;
32 git_revpool
*gitrp_alloc(git_odb
*db
)
34 git_revpool
*walk
= git__malloc(sizeof(*walk
));
38 memset(walk
, 0x0, sizeof(git_revpool
));
40 walk
->commits
= git_revpool_table_create(default_table_size
);
46 void gitrp_free(git_revpool
*walk
)
48 git_commit_list_clear(&(walk
->iterator
), 0);
49 git_commit_list_clear(&(walk
->roots
), 0);
51 git_revpool_table_free(walk
->commits
);
56 void gitrp_sorting(git_revpool
*pool
, unsigned int sort_mode
)
61 pool
->sorting
= sort_mode
;
65 int gitrp_push(git_revpool
*pool
, git_commit
*commit
)
67 if (commit
== NULL
|| commit
->seen
)
70 if (commit
->object
.pool
!= pool
|| pool
->walking
)
73 if (!commit
->parsed
) {
74 int error
= git_commit_parse_existing(commit
);
80 * Sanity check: make sure that if the commit
81 * has been manually marked as uninteresting,
82 * all the parent commits are too.
84 if (commit
->uninteresting
)
85 git_commit__mark_uninteresting(commit
);
87 if (git_commit_list_push_back(&pool
->roots
, commit
) < 0)
93 int gitrp_hide(git_revpool
*pool
, git_commit
*commit
)
98 git_commit__mark_uninteresting(commit
);
99 return gitrp_push(pool
, commit
);
102 int gitrp__enroot(git_revpool
*pool
, git_commit
*commit
)
105 git_commit_node
*parents
;
110 if (commit
->parsed
== 0) {
111 error
= git_commit_parse_existing(commit
);
118 for (parents
= commit
->parents
.head
; parents
!= NULL
; parents
= parents
->next
) {
119 parents
->commit
->in_degree
++;
121 error
= gitrp__enroot(pool
, parents
->commit
);
126 if (git_commit_list_push_back(&pool
->iterator
, commit
))
132 void gitrp__prepare_walk(git_revpool
*pool
)
136 for (it
= pool
->roots
.head
; it
!= NULL
; it
= it
->next
)
137 gitrp__enroot(pool
, it
->commit
);
139 if (pool
->sorting
& GIT_RPSORT_TIME
)
140 git_commit_list_timesort(&pool
->iterator
);
142 if (pool
->sorting
& GIT_RPSORT_TOPOLOGICAL
)
143 git_commit_list_toposort(&pool
->iterator
);
145 if (pool
->sorting
& GIT_RPSORT_REVERSE
)
146 pool
->next_commit
= &git_commit_list_pop_back
;
148 pool
->next_commit
= &git_commit_list_pop_front
;
153 git_commit
*gitrp_next(git_revpool
*pool
)
158 gitrp__prepare_walk(pool
);
160 while ((next
= pool
->next_commit(&pool
->iterator
)) != NULL
) {
161 if (!next
->uninteresting
)
165 /* No commits left to iterate */
170 void gitrp_reset(git_revpool
*pool
)
173 git_revpool_tableit it
;
175 git_revpool_tableit_init(pool
->commits
, &it
);
177 while ((commit
= (git_commit
*)git_revpool_tableit_next(&it
)) != NULL
) {
179 commit
->topo_delay
= 0;
180 commit
->in_degree
= 0;
183 git_commit_list_clear(&pool
->iterator
, 0);