Browse Source

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>
maint
Johannes Schindelin 19 years ago committed by Junio C Hamano
parent
commit
070879ca93
  1. 5
      fsck-objects.c
  2. 7
      name-rev.c
  3. 69
      object.c
  4. 2
      object.h

5
fsck-objects.c

@ -61,9 +61,12 @@ static void check_connectivity(void) @@ -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 */

7
name-rev.c

@ -232,9 +232,10 @@ int main(int argc, char **argv) @@ -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));

69
object.c

@ -6,30 +6,32 @@ @@ -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;

while (first < last) {
int next = (first + last) / 2;
struct object *obj = objs[next];
int cmp;

cmp = memcmp(sha1, obj->sha1, 20);
if (!cmp)
return next;
if (cmp < 0) {
last = next;
continue;
}
first = next+1;
}
return -first-1;
int i = hashtable_index(sha1);

if (!objs)
return -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) @@ -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,18 +52,27 @@ void created_object(const unsigned char *sha1, struct object *obj) @@ -50,18 +52,27 @@ void created_object(const unsigned char *sha1, struct object *obj)
obj->refs = NULL;
obj->used = 0;

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);
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;
}
}
}

/* Insert it into the right place */
memmove(objs + pos + 1, objs + pos, (nr_objs - pos) *
sizeof(struct object *));
pos = find_object(sha1);
if (pos >= 0)
die("Inserting %s twice\n", sha1_to_hex(sha1));
pos = -pos-1;

objs[pos] = obj;
nr_objs++;

2
object.h

@ -23,7 +23,7 @@ struct object { @@ -23,7 +23,7 @@ struct object {
};

extern int track_object_refs;
extern int nr_objs;
extern int obj_allocs;
extern struct object **objs;

/** Internal only **/

Loading…
Cancel
Save