summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>2006-02-12 02:57:57 +0100
committerJunio C Hamano <junkio@cox.net>2006-02-12 05:12:39 -0800
commit070879ca93a7d358086f4c8aff4553493dcb9210 (patch)
tree741a4ebdfc6cb5898c5229d9d2b78c03ad5aafc4
parent5b766ea9014b4121cb72f424633b6bf9a97308a0 (diff)
downloadgit-070879ca93a7d358086f4c8aff4553493dcb9210.tar.gz
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>
-rw-r--r--fsck-objects.c5
-rw-r--r--name-rev.c7
-rw-r--r--object.c69
-rw-r--r--object.h2
4 files changed, 49 insertions, 34 deletions
diff --git a/fsck-objects.c b/fsck-objects.c
index 9950be2645..6439d55126 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -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 */
diff --git a/name-rev.c b/name-rev.c
index bbadb91aa0..0c3f547622 100644
--- a/name-rev.c
+++ b/name-rev.c
@@ -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));
diff --git a/object.c b/object.c
index 1577f74281..3259862ab2 100644
--- a/object.c
+++ b/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;
-
- 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)
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)
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++;
diff --git a/object.h b/object.h
index 0e7618283c..e08afbd29f 100644
--- a/object.h
+++ b/object.h
@@ -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 **/