Use a hashtable for objects instead of a sorted list
In a simple test, this brings down the CPU time from 47 sec to 22 sec. Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
5b766ea901
commit
070879ca93
@ -61,9 +61,12 @@ static void check_connectivity(void)
|
||||
int i;
|
||||
|
||||
/* Look up all the requirements, warn about missing objects.. */
|
||||
for (i = 0; i < nr_objs; i++) {
|
||||
for (i = 0; i < obj_allocs; i++) {
|
||||
struct object *obj = objs[i];
|
||||
|
||||
if (!obj)
|
||||
continue;
|
||||
|
||||
if (!obj->parsed) {
|
||||
if (!standalone && has_sha1_file(obj->sha1))
|
||||
; /* it is in pack */
|
||||
|
@ -232,9 +232,10 @@ int main(int argc, char **argv)
|
||||
} else if (all) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_objs; i++)
|
||||
printf("%s %s\n", sha1_to_hex(objs[i]->sha1),
|
||||
get_rev_name(objs[i]));
|
||||
for (i = 0; i < obj_allocs; i++)
|
||||
if (objs[i])
|
||||
printf("%s %s\n", sha1_to_hex(objs[i]->sha1),
|
||||
get_rev_name(objs[i]));
|
||||
} else
|
||||
for ( ; revs; revs = revs->next)
|
||||
printf("%s %s\n", revs->name, get_rev_name(revs->item));
|
||||
|
65
object.c
65
object.c
@ -6,30 +6,32 @@
|
||||
#include "tag.h"
|
||||
|
||||
struct object **objs;
|
||||
int nr_objs;
|
||||
static int obj_allocs;
|
||||
static int nr_objs;
|
||||
int obj_allocs;
|
||||
|
||||
int track_object_refs = 1;
|
||||
|
||||
static int hashtable_index(const unsigned char *sha1)
|
||||
{
|
||||
unsigned int i = *(unsigned int *)sha1;
|
||||
return (int)(i % obj_allocs);
|
||||
}
|
||||
|
||||
static int find_object(const unsigned char *sha1)
|
||||
{
|
||||
int first = 0, last = nr_objs;
|
||||
int i = hashtable_index(sha1);
|
||||
|
||||
while (first < last) {
|
||||
int next = (first + last) / 2;
|
||||
struct object *obj = objs[next];
|
||||
int cmp;
|
||||
if (!objs)
|
||||
return -1;
|
||||
|
||||
cmp = memcmp(sha1, obj->sha1, 20);
|
||||
if (!cmp)
|
||||
return next;
|
||||
if (cmp < 0) {
|
||||
last = next;
|
||||
continue;
|
||||
}
|
||||
first = next+1;
|
||||
}
|
||||
return -first-1;
|
||||
while (objs[i]) {
|
||||
if (memcmp(sha1, objs[i]->sha1, 20) == 0)
|
||||
return i;
|
||||
i++;
|
||||
if (i == obj_allocs)
|
||||
i = 0;
|
||||
}
|
||||
return -1 - i;
|
||||
}
|
||||
|
||||
struct object *lookup_object(const unsigned char *sha1)
|
||||
@ -42,7 +44,7 @@ struct object *lookup_object(const unsigned char *sha1)
|
||||
|
||||
void created_object(const unsigned char *sha1, struct object *obj)
|
||||
{
|
||||
int pos = find_object(sha1);
|
||||
int pos;
|
||||
|
||||
obj->parsed = 0;
|
||||
memcpy(obj->sha1, sha1, 20);
|
||||
@ -50,19 +52,28 @@ void created_object(const unsigned char *sha1, struct object *obj)
|
||||
obj->refs = NULL;
|
||||
obj->used = 0;
|
||||
|
||||
if (obj_allocs - 1 <= nr_objs * 2) {
|
||||
int i, count = obj_allocs;
|
||||
obj_allocs = (obj_allocs < 32 ? 32 : 2 * obj_allocs);
|
||||
objs = xrealloc(objs, obj_allocs * sizeof(struct object *));
|
||||
memset(objs + count, 0, (obj_allocs - count)
|
||||
* sizeof(struct object *));
|
||||
for (i = 0; i < count; i++)
|
||||
if (objs[i]) {
|
||||
int j = find_object(objs[i]->sha1);
|
||||
if (j != i) {
|
||||
j = -1 - j;
|
||||
objs[j] = objs[i];
|
||||
objs[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos = find_object(sha1);
|
||||
if (pos >= 0)
|
||||
die("Inserting %s twice\n", sha1_to_hex(sha1));
|
||||
pos = -pos-1;
|
||||
|
||||
if (obj_allocs == nr_objs) {
|
||||
obj_allocs = alloc_nr(obj_allocs);
|
||||
objs = xrealloc(objs, obj_allocs * sizeof(struct object *));
|
||||
}
|
||||
|
||||
/* Insert it into the right place */
|
||||
memmove(objs + pos + 1, objs + pos, (nr_objs - pos) *
|
||||
sizeof(struct object *));
|
||||
|
||||
objs[pos] = obj;
|
||||
nr_objs++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user