Skip to content

Commit f2ee60f

Browse files
spkrkagitster
authored andcommitted
commit-reach: optimize queue scan in ahead_behind
Apply the same nonstale_count optimization from the previous commit to ahead_behind(). This replaces the remaining caller of the O(n) queue_has_nonstale() scan with an O(1) counter check, allowing queue_has_nonstale() to be removed. ahead_behind() already deduplicates queue entries using the PARENT2 flag (via insert_no_dup), so the counter is maintained through insert_no_dup() and mark_stale() using PARENT2 as the queued_flag. Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent e742e7d commit f2ee60f

1 file changed

Lines changed: 12 additions & 15 deletions

File tree

commit-reach.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,6 @@ static void mark_stale(struct commit *c, unsigned queued_flag,
6161
}
6262
}
6363

64-
static int queue_has_nonstale(struct prio_queue *queue)
65-
{
66-
for (size_t i = 0; i < queue->nr; i++) {
67-
struct commit *commit = queue->array[i].data;
68-
if (!(commit->object.flags & STALE))
69-
return 1;
70-
}
71-
return 0;
72-
}
73-
7464
/* all input commits in one and twos[] must have been parsed! */
7565
static int paint_down_to_common(struct repository *r,
7666
struct commit *one, int n,
@@ -1051,12 +1041,15 @@ struct commit_list *get_reachable_subset(struct commit **from, size_t nr_from,
10511041
define_commit_slab(bit_arrays, struct bitmap *);
10521042
static struct bit_arrays bit_arrays;
10531043

1054-
static void insert_no_dup(struct prio_queue *queue, struct commit *c)
1044+
static void insert_no_dup(struct prio_queue *queue, struct commit *c,
1045+
int *nonstale_count)
10551046
{
10561047
if (c->object.flags & PARENT2)
10571048
return;
10581049
prio_queue_put(queue, c);
10591050
c->object.flags |= PARENT2;
1051+
if (!(c->object.flags & STALE))
1052+
(*nonstale_count)++;
10601053
}
10611054

10621055
static struct bitmap *get_bit_array(struct commit *c, int width)
@@ -1082,6 +1075,7 @@ void ahead_behind(struct repository *r,
10821075
{
10831076
struct prio_queue queue = { .compare = compare_commits_by_gen_then_commit_date };
10841077
size_t width = DIV_ROUND_UP(commits_nr, BITS_IN_EWORD);
1078+
int nonstale_count = 0;
10851079

10861080
if (!commits_nr || !counts_nr)
10871081
return;
@@ -1100,14 +1094,17 @@ void ahead_behind(struct repository *r,
11001094
struct bitmap *bitmap = get_bit_array(c, width);
11011095

11021096
bitmap_set(bitmap, i);
1103-
insert_no_dup(&queue, c);
1097+
insert_no_dup(&queue, c, &nonstale_count);
11041098
}
11051099

1106-
while (queue_has_nonstale(&queue)) {
1100+
while (nonstale_count > 0) {
11071101
struct commit *c = prio_queue_get(&queue);
11081102
struct commit_list *p;
11091103
struct bitmap *bitmap_c = get_bit_array(c, width);
11101104

1105+
if (!(c->object.flags & STALE))
1106+
nonstale_count--;
1107+
11111108
for (size_t i = 0; i < counts_nr; i++) {
11121109
int reach_from_tip = !!bitmap_get(bitmap_c, counts[i].tip_index);
11131110
int reach_from_base = !!bitmap_get(bitmap_c, counts[i].base_index);
@@ -1136,9 +1133,9 @@ void ahead_behind(struct repository *r,
11361133
* queue is STALE.
11371134
*/
11381135
if (bitmap_popcount(bitmap_p) == commits_nr)
1139-
p->item->object.flags |= STALE;
1136+
mark_stale(p->item, PARENT2, &nonstale_count);
11401137

1141-
insert_no_dup(&queue, p->item);
1138+
insert_no_dup(&queue, p->item, &nonstale_count);
11421139
}
11431140

11441141
free_bit_array(c);

0 commit comments

Comments
 (0)