40
return 0;
41
}
42
43
-static void prio_queue_put_dedup(struct prio_queue *queue, struct commit *c)
43
+/*
44
+ * A prio_queue with O(1) termination check. 'max_nonstale' tracks
45
+ * the lowest-priority non-stale commit enqueued so far; once it is
46
+ * popped, every remaining entry is known to be STALE.
47
+ */
48
+struct nonstale_queue {
49
+ struct prio_queue pq;
50
+ struct commit *max_nonstale;
51
+};
52
+
53
+static void nonstale_queue_put(struct nonstale_queue *queue,
54
+ struct commit *c)
55
+{
56
+ struct commit *old = queue->max_nonstale;
57
+
58
+ prio_queue_put(&queue->pq, c);
59
+ if (c->object.flags & STALE)
60
+ return;
61
+ if (!old || queue->pq.compare(old, c, queue->pq.cb_data) <= 0)
62
+ queue->max_nonstale = c;
63
+}
64
+
65
+static struct commit *nonstale_queue_get(struct nonstale_queue *queue)
66
+{
67
+ struct commit *commit = prio_queue_get(&queue->pq);
68
+
69
+ if (commit == queue->max_nonstale)
70
+ queue->max_nonstale = NULL;
71
+
72
+ return commit;
73
+}
74
+
75
+static void clear_nonstale_queue(struct nonstale_queue *queue)
76
+{
77
+ clear_prio_queue(&queue->pq);
78
+ queue->max_nonstale = NULL;
79
+}
80
+
81
+static void nonstale_queue_put_dedup(struct nonstale_queue *queue,
82
+ struct commit *c)
83
{
84
if (c->object.flags & ENQUEUED)
85
return;
86
c->object.flags |= ENQUEUED;
48
- prio_queue_put(queue, c);
87
+ nonstale_queue_put(queue, c);
88
}
89
51
-static struct commit *prio_queue_get_dedup(struct prio_queue *queue)
90
+static struct commit *nonstale_queue_get_dedup(struct nonstale_queue *queue)
91
{
53
- struct commit *commit = prio_queue_get(queue);
92
+ struct commit *commit = nonstale_queue_get(queue);
93
+
94
if (commit)
95
commit->object.flags &= ~ENQUEUED;
96
return commit;
97
}
98
59
-static int queue_has_nonstale(struct prio_queue *queue)
60
-{
61
- for (size_t i = 0; i < queue->nr; i++) {
62
- struct commit *commit = queue->array[i].data;
63
- if (!(commit->object.flags & STALE))
64
- return 1;
65
- }
66
- return 0;
67
-}
68
-
99
/* all input commits in one and twos[] must have been parsed! */
100
static int paint_down_to_common(struct repository *r,
101
struct commit *one, int n,
104
int ignore_missing_commits,
105
struct commit_list **result)
106
{
77
- struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
107
+ struct nonstale_queue queue = {
108
+ { compare_commits_by_gen_then_commit_date }
109
+ };
110
int i;
111
timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
112
struct commit_list **tail = result;
113
114
if (!min_generation && !corrected_commit_dates_enabled(r))
83
- queue.compare = compare_commits_by_commit_date;
115
+ queue.pq.compare = compare_commits_by_commit_date;
116
117
one->object.flags |= PARENT1;
118
if (!n) {
119
commit_list_append(one, result);
120
return 0;
121
}
90
- prio_queue_put_dedup(&queue, one);
122
+ nonstale_queue_put_dedup(&queue, one);
123
124
for (i = 0; i < n; i++) {
125
twos[i]->object.flags |= PARENT2;
94
- prio_queue_put_dedup(&queue, twos[i]);
126
+ nonstale_queue_put_dedup(&queue, twos[i]);
127
}
128
97
- while (queue_has_nonstale(&queue)) {
98
- struct commit *commit = prio_queue_get_dedup(&queue);
129
+ while (queue.max_nonstale) {
130
+ struct commit *commit = nonstale_queue_get_dedup(&queue);
131
struct commit_list *parents;
132
int flags;
133
timestamp_t generation = commit_graph_generation(commit);
157
if ((p->object.flags & flags) == flags)
158
continue;
159
if (repo_parse_commit(r, p)) {
128
- clear_prio_queue(&queue);
160
+ clear_nonstale_queue(&queue);
161
commit_list_free(*result);
162
*result = NULL;
163
/*
173
oid_to_hex(&p->object.oid));
174
}
175
p->object.flags |= flags;
144
- prio_queue_put_dedup(&queue, p);
176
+ nonstale_queue_put_dedup(&queue, p);
177
}
178
}
179
148
- clear_prio_queue(&queue);
180
+ clear_nonstale_queue(&queue);
181
commit_list_sort_by_date(result);
182
return 0;
183
}
1071
define_commit_slab(bit_arrays, struct bitmap *);
1072
static struct bit_arrays bit_arrays;
1073
1042
-static void insert_no_dup(struct prio_queue *queue, struct commit *c)
1074
+static void insert_no_dup(struct nonstale_queue *queue, struct commit *c)
1075
{
1076
if (c->object.flags & PARENT2)
1077
return;
1046
- prio_queue_put(queue, c);
1078
+ nonstale_queue_put(queue, c);
1079
c->object.flags |= PARENT2;
1080
}
1081
1100
struct commit **commits, size_t commits_nr,
1101
struct ahead_behind_count *counts, size_t counts_nr)
1102
{
1071
- struct prio_queue queue = { .compare = compare_commits_by_gen_then_commit_date };
1103
+ struct nonstale_queue queue = {
1104
+ { .compare = compare_commits_by_gen_then_commit_date }
1105
+ };
1106
size_t width = DIV_ROUND_UP(commits_nr, BITS_IN_EWORD);
1107
1108
if (!commits_nr || !counts_nr)
1125
insert_no_dup(&queue, c);
1126
}
1127
1094
- while (queue_has_nonstale(&queue)) {
1095
- struct commit *c = prio_queue_get(&queue);
1128
+ while (queue.max_nonstale) {
1129
+ struct commit *c = nonstale_queue_get(&queue);
1130
struct commit_list *p;
1131
struct bitmap *bitmap_c = get_bit_array(c, width);
1132
1168
1169
/* STALE is used here, PARENT2 is used by insert_no_dup(). */
1170
repo_clear_commit_marks(r, PARENT2 | STALE);
1137
- for (size_t i = 0; i < queue.nr; i++)
1138
- free_bit_array(queue.array[i].data);
1171
+ for (size_t i = 0; i < queue.pq.nr; i++)
1172
+ free_bit_array(queue.pq.array[i].data);
1173
clear_bit_arrays(&bit_arrays);
1140
- clear_prio_queue(&queue);
1174
+ clear_nonstale_queue(&queue);
1175
}
1176
1177
struct commit_and_index {