79
queue->max_nonstale = NULL;
80
}
81
82
-static void nonstale_queue_put_dedup(struct nonstale_queue *queue,
83
- struct commit *c)
82
+/*
83
+ * Priority queue with per-side commit counters for paint_down_to_common().
84
+ * Each non-stale queued commit occupies exactly one bucket: PARENT1-only,
85
+ * PARENT2-only, or both (a pending merge-base candidate).
86
+ */
87
+struct paint_state {
88
+ struct prio_queue queue;
89
+ size_t parent1_count;
90
+ size_t parent2_count;
91
+ size_t mb_candidate_count;
92
+ int gen_ordered;
93
+};
94
+
95
+static void paint_count_update(struct paint_state *state,
96
+ unsigned flags, int delta)
97
{
85
- if (c->object.flags & ENQUEUED)
86
- return;
87
- c->object.flags |= ENQUEUED;
88
- nonstale_queue_put(queue, c);
98
+ switch (flags & (PARENT1 | PARENT2 | STALE)) {
99
+ case PARENT1:
100
+ state->parent1_count += delta;
101
+ break;
102
+
103
+ case PARENT2:
104
+ state->parent2_count += delta;
105
+ break;
106
+
107
+ case PARENT1 | PARENT2:
108
+ state->mb_candidate_count += delta;
109
+ break;
110
+
111
+ case PARENT1 | PARENT2 | STALE:
112
+ break;
113
+
114
+ default:
115
+ BUG("unexpected paint state");
116
+ }
117
+}
118
+
119
+static void paint_queue_put(struct paint_state *state,
120
+ struct commit *c, unsigned add_flags)
121
+{
122
+ unsigned old_flags = c->object.flags;
123
+ c->object.flags |= add_flags;
124
+
125
+ if (old_flags & ENQUEUED) {
126
+ paint_count_update(state, old_flags, -1);
127
+ paint_count_update(state, c->object.flags, 1);
128
+ } else {
129
+ c->object.flags |= ENQUEUED;
130
+ prio_queue_put(&state->queue, c);
131
+ paint_count_update(state, c->object.flags, 1);
132
+ }
133
}
134
91
-static struct commit *nonstale_queue_get_dedup(struct nonstale_queue *queue)
135
+static struct commit *paint_queue_get(struct paint_state *state)
136
{
93
- struct commit *commit = nonstale_queue_get(queue);
137
+ struct commit *commit = prio_queue_get(&state->queue);
138
+
139
+ if (!commit)
140
+ return NULL;
141
+
142
+ commit->object.flags &= ~ENQUEUED;
143
+
144
+ if (!state->parent1_count && !state->parent2_count &&
145
+ !state->mb_candidate_count)
146
+ return NULL;
147
95
- if (commit)
96
- commit->object.flags &= ~ENQUEUED;
148
+ paint_count_update(state, commit->object.flags, -1);
149
return commit;
150
}
151
161
enum merge_base_flags mb_flags,
162
struct commit_list **result)
163
{
112
- struct nonstale_queue queue = {
113
- { compare_commits_by_gen_then_commit_date }
164
+ struct paint_state state = {
165
+ .queue = { compare_commits_by_gen_then_commit_date },
166
+ .gen_ordered = 1,
167
};
168
+ struct commit *commit;
169
int i;
116
- int gen_ordered = 1;
170
int steps = 0;
171
timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
172
struct commit_list **tail = result;
173
174
if (!min_generation && !corrected_commit_dates_enabled(r)) {
122
- queue.pq.compare = compare_commits_by_commit_date;
123
- gen_ordered = 0;
175
+ state.queue.compare = compare_commits_by_commit_date;
176
+ state.gen_ordered = 0;
177
}
178
179
one->object.flags |= PARENT1;
181
commit_list_append(one, result);
182
return 0;
183
}
131
- nonstale_queue_put_dedup(&queue, one);
184
+ paint_queue_put(&state, one, 0);
185
133
- for (i = 0; i < n; i++) {
134
- twos[i]->object.flags |= PARENT2;
135
- nonstale_queue_put_dedup(&queue, twos[i]);
136
- }
186
+ for (i = 0; i < n; i++)
187
+ paint_queue_put(&state, twos[i], PARENT2);
188
138
- while (queue.max_nonstale) {
139
- struct commit *commit = nonstale_queue_get_dedup(&queue);
189
+ while ((commit = paint_queue_get(&state))) {
190
struct commit_list *parents;
191
int flags;
192
timestamp_t generation = commit_graph_generation(commit);
212
* descendant of this one.
213
*/
214
if (!(mb_flags & MERGE_BASE_FIND_ALL) &&
165
- gen_ordered &&
215
+ state.gen_ordered &&
216
generation < GENERATION_NUMBER_INFINITY)
217
break;
218
}
226
if ((p->object.flags & flags) == flags)
227
continue;
228
if (repo_parse_commit(r, p)) {
179
- clear_nonstale_queue(&queue);
229
+ clear_prio_queue(&state.queue);
230
commit_list_free(*result);
231
*result = NULL;
232
/*
241
return error(_("could not parse commit %s"),
242
oid_to_hex(&p->object.oid));
243
}
194
- p->object.flags |= flags;
195
- nonstale_queue_put_dedup(&queue, p);
244
+ paint_queue_put(&state, p, flags);
245
}
246
}
247
199
- clear_nonstale_queue(&queue);
248
+ clear_prio_queue(&state.queue);
249
trace2_data_intmax("paint_down_to_common", r,
250
"steps", steps);
251
commit_list_sort_by_date(result);