Merge branch 'jp/refs'
* jp/refs: refs.c: add a function to sort a ref list, rather then sorting on add
This commit is contained in:
commit
e32442a676
110
refs.c
110
refs.c
@ -47,22 +47,7 @@ static struct ref_list *add_ref(const char *name, const unsigned char *sha1,
|
||||
struct ref_list **new_entry)
|
||||
{
|
||||
int len;
|
||||
struct ref_list **p = &list, *entry;
|
||||
|
||||
/* Find the place to insert the ref into.. */
|
||||
while ((entry = *p) != NULL) {
|
||||
int cmp = strcmp(entry->name, name);
|
||||
if (cmp > 0)
|
||||
break;
|
||||
|
||||
/* Same as existing entry? */
|
||||
if (!cmp) {
|
||||
if (new_entry)
|
||||
*new_entry = entry;
|
||||
return list;
|
||||
}
|
||||
p = &entry->next;
|
||||
}
|
||||
struct ref_list *entry;
|
||||
|
||||
/* Allocate it and add it in.. */
|
||||
len = strlen(name) + 1;
|
||||
@ -71,11 +56,94 @@ static struct ref_list *add_ref(const char *name, const unsigned char *sha1,
|
||||
hashclr(entry->peeled);
|
||||
memcpy(entry->name, name, len);
|
||||
entry->flag = flag;
|
||||
entry->next = *p;
|
||||
*p = entry;
|
||||
entry->next = list;
|
||||
if (new_entry)
|
||||
*new_entry = entry;
|
||||
return list;
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* merge sort the ref list */
|
||||
static struct ref_list *sort_ref_list(struct ref_list *list)
|
||||
{
|
||||
int psize, qsize, last_merge_count, cmp;
|
||||
struct ref_list *p, *q, *l, *e;
|
||||
struct ref_list *new_list = list;
|
||||
int k = 1;
|
||||
int merge_count = 0;
|
||||
|
||||
if (!list)
|
||||
return list;
|
||||
|
||||
do {
|
||||
last_merge_count = merge_count;
|
||||
merge_count = 0;
|
||||
|
||||
psize = 0;
|
||||
|
||||
p = new_list;
|
||||
q = new_list;
|
||||
new_list = NULL;
|
||||
l = NULL;
|
||||
|
||||
while (p) {
|
||||
merge_count++;
|
||||
|
||||
while (psize < k && q->next) {
|
||||
q = q->next;
|
||||
psize++;
|
||||
}
|
||||
qsize = k;
|
||||
|
||||
while ((psize > 0) || (qsize > 0 && q)) {
|
||||
if (qsize == 0 || !q) {
|
||||
e = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
} else if (psize == 0) {
|
||||
e = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
} else {
|
||||
cmp = strcmp(q->name, p->name);
|
||||
if (cmp < 0) {
|
||||
e = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
} else if (cmp > 0) {
|
||||
e = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
} else {
|
||||
if (hashcmp(q->sha1, p->sha1))
|
||||
die("Duplicated ref, and SHA1s don't match: %s",
|
||||
q->name);
|
||||
warning("Duplicated ref: %s", q->name);
|
||||
e = q;
|
||||
q = q->next;
|
||||
qsize--;
|
||||
free(e);
|
||||
e = p;
|
||||
p = p->next;
|
||||
psize--;
|
||||
}
|
||||
}
|
||||
|
||||
e->next = NULL;
|
||||
|
||||
if (l)
|
||||
l->next = e;
|
||||
if (!new_list)
|
||||
new_list = e;
|
||||
l = e;
|
||||
}
|
||||
|
||||
p = q;
|
||||
};
|
||||
|
||||
k = k * 2;
|
||||
} while ((last_merge_count != merge_count) || (last_merge_count != 1));
|
||||
|
||||
return new_list;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -142,7 +210,7 @@ static void read_packed_refs(FILE *f, struct cached_refs *cached_refs)
|
||||
!get_sha1_hex(refline + 1, sha1))
|
||||
hashcpy(last->peeled, sha1);
|
||||
}
|
||||
cached_refs->packed = list;
|
||||
cached_refs->packed = sort_ref_list(list);
|
||||
}
|
||||
|
||||
static struct ref_list *get_packed_refs(void)
|
||||
@ -201,7 +269,7 @@ static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
|
||||
free(ref);
|
||||
closedir(dir);
|
||||
}
|
||||
return list;
|
||||
return sort_ref_list(list);
|
||||
}
|
||||
|
||||
static struct ref_list *get_loose_refs(void)
|
||||
|
Loading…
Reference in New Issue
Block a user