combine-diff: simplify intersect_paths() further
Linus once said: I actually wish more people understood the really core low-level kind of coding. Not big, complex stuff like the lockless name lookup, but simply good use of pointers-to-pointers etc. For example, I've seen too many people who delete a singly-linked list entry by keeping track of the "prev" entry, and then to delete the entry, doing something like if (prev) prev->next = entry->next; else list_head = entry->next; and whenever I see code like that, I just go "This person doesn't understand pointers". And it's sadly quite common. People who understand pointers just use a "pointer to the entry pointer", and initialize that with the address of the list_head. And then as they traverse the list, they can remove the entry without using any conditionals, by just doing a "*pp = entry->next". Applying that simplification lets us lose 7 lines from this function even while adding 2 lines of comment. I was tempted to squash this into the original commit, but because the benchmarking described in the commit log is without this simplification, I decided to keep it a separate follow-up patch. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
@ -15,11 +15,10 @@
|
|||||||
static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
|
static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
|
||||||
{
|
{
|
||||||
struct diff_queue_struct *q = &diff_queued_diff;
|
struct diff_queue_struct *q = &diff_queued_diff;
|
||||||
struct combine_diff_path *p, *pprev, *ptmp;
|
struct combine_diff_path *p, **tail = &curr;
|
||||||
int i, cmp;
|
int i, cmp;
|
||||||
|
|
||||||
if (!n) {
|
if (!n) {
|
||||||
struct combine_diff_path *list = NULL, **tail = &list;
|
|
||||||
for (i = 0; i < q->nr; i++) {
|
for (i = 0; i < q->nr; i++) {
|
||||||
int len;
|
int len;
|
||||||
const char *path;
|
const char *path;
|
||||||
@ -43,35 +42,27 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
|
|||||||
*tail = p;
|
*tail = p;
|
||||||
tail = &p->next;
|
tail = &p->next;
|
||||||
}
|
}
|
||||||
return list;
|
return curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE paths are coming sorted here (= in tree order)
|
* paths in curr (linked list) and q->queue[] (array) are
|
||||||
|
* both sorted in the tree order.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pprev = NULL;
|
|
||||||
p = curr;
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
while ((p = *tail) != NULL) {
|
||||||
|
cmp = ((i >= q->nr)
|
||||||
|
? -1 : strcmp(p->path, q->queue[i]->two->path));
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (!p)
|
|
||||||
break;
|
|
||||||
|
|
||||||
cmp = (i >= q->nr) ? -1
|
|
||||||
: strcmp(p->path, q->queue[i]->two->path);
|
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
if (pprev)
|
/* p->path not in q->queue[]; drop it */
|
||||||
pprev->next = p->next;
|
*tail = p->next;
|
||||||
ptmp = p;
|
free(p);
|
||||||
p = p->next;
|
|
||||||
free(ptmp);
|
|
||||||
if (curr == ptmp)
|
|
||||||
curr = p;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
|
/* q->queue[i] not in p->path; skip it */
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -80,8 +71,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
|
|||||||
p->parent[n].mode = q->queue[i]->one->mode;
|
p->parent[n].mode = q->queue[i]->one->mode;
|
||||||
p->parent[n].status = q->queue[i]->status;
|
p->parent[n].status = q->queue[i]->status;
|
||||||
|
|
||||||
pprev = p;
|
tail = &p->next;
|
||||||
p = p->next;
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return curr;
|
return curr;
|
||||||
|
Reference in New Issue
Block a user