Skip to content

Commit 0556a11

Browse files
Linus TorvaldsJunio C Hamano
Linus Torvalds
authored and
Junio C Hamano
committed
git object hash cleanups
This IMNSHO cleans up the object hashing. The hash expansion is separated out into a function of its own, the hash array (and size) names are made more obvious, and the code is generally made to look a bit more like the object-ref hashing. It also gets rid of "find_object()" returning an index (or negative position if no object is found), since that is made redundant by the simplified object rehashing. The basic operation is now "lookup_object()" which just returns the object itself. There's an almost unmeasurable speed increase, but more importantly, I think the end result is more readable. Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6631c73 commit 0556a11

File tree

1 file changed

+53
-44
lines changed

1 file changed

+53
-44
lines changed

object.c

+53-44
Original file line numberDiff line numberDiff line change
@@ -5,88 +5,97 @@
55
#include "commit.h"
66
#include "tag.h"
77

8-
static struct object **objs;
9-
static int nr_objs, obj_allocs;
8+
static struct object **obj_hash;
9+
static int nr_objs, obj_hash_size;
1010

1111
unsigned int get_max_object_index(void)
1212
{
13-
return obj_allocs;
13+
return obj_hash_size;
1414
}
1515

1616
struct object *get_indexed_object(unsigned int idx)
1717
{
18-
return objs[idx];
18+
return obj_hash[idx];
1919
}
2020

2121
const char *type_names[] = {
2222
"none", "blob", "tree", "commit", "bad"
2323
};
2424

25+
static unsigned int hash_obj(struct object *obj, unsigned int n)
26+
{
27+
unsigned int hash = *(unsigned int *)obj->sha1;
28+
return hash % n;
29+
}
30+
31+
static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size)
32+
{
33+
int j = hash_obj(obj, size);
34+
35+
while (hash[j]) {
36+
j++;
37+
if (j >= size)
38+
j = 0;
39+
}
40+
hash[j] = obj;
41+
}
42+
2543
static int hashtable_index(const unsigned char *sha1)
2644
{
2745
unsigned int i;
2846
memcpy(&i, sha1, sizeof(unsigned int));
29-
return (int)(i % obj_allocs);
47+
return (int)(i % obj_hash_size);
3048
}
3149

32-
static int find_object(const unsigned char *sha1)
50+
struct object *lookup_object(const unsigned char *sha1)
3351
{
3452
int i;
53+
struct object *obj;
3554

36-
if (!objs)
37-
return -1;
55+
if (!obj_hash)
56+
return NULL;
3857

3958
i = hashtable_index(sha1);
40-
while (objs[i]) {
41-
if (memcmp(sha1, objs[i]->sha1, 20) == 0)
42-
return i;
59+
while ((obj = obj_hash[i]) != NULL) {
60+
if (!memcmp(sha1, obj->sha1, 20))
61+
break;
4362
i++;
44-
if (i == obj_allocs)
63+
if (i == obj_hash_size)
4564
i = 0;
4665
}
47-
return -1 - i;
66+
return obj;
4867
}
4968

50-
struct object *lookup_object(const unsigned char *sha1)
69+
static void grow_object_hash(void)
5170
{
52-
int pos = find_object(sha1);
53-
if (pos >= 0)
54-
return objs[pos];
55-
return NULL;
71+
int i;
72+
int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size;
73+
struct object **new_hash;
74+
75+
new_hash = calloc(new_hash_size, sizeof(struct object *));
76+
for (i = 0; i < obj_hash_size; i++) {
77+
struct object *obj = obj_hash[i];
78+
if (!obj)
79+
continue;
80+
insert_obj_hash(obj, new_hash, new_hash_size);
81+
}
82+
free(obj_hash);
83+
obj_hash = new_hash;
84+
obj_hash_size = new_hash_size;
5685
}
5786

5887
void created_object(const unsigned char *sha1, struct object *obj)
5988
{
60-
int pos;
61-
6289
obj->parsed = 0;
63-
memcpy(obj->sha1, sha1, 20);
64-
obj->type = TYPE_NONE;
6590
obj->used = 0;
91+
obj->type = TYPE_NONE;
92+
obj->flags = 0;
93+
memcpy(obj->sha1, sha1, 20);
6694

67-
if (obj_allocs - 1 <= nr_objs * 2) {
68-
int i, count = obj_allocs;
69-
obj_allocs = (obj_allocs < 32 ? 32 : 2 * obj_allocs);
70-
objs = xrealloc(objs, obj_allocs * sizeof(struct object *));
71-
memset(objs + count, 0, (obj_allocs - count)
72-
* sizeof(struct object *));
73-
for (i = 0; i < obj_allocs; i++)
74-
if (objs[i]) {
75-
int j = find_object(objs[i]->sha1);
76-
if (j != i) {
77-
j = -1 - j;
78-
objs[j] = objs[i];
79-
objs[i] = NULL;
80-
}
81-
}
82-
}
83-
84-
pos = find_object(sha1);
85-
if (pos >= 0)
86-
die("Inserting %s twice\n", sha1_to_hex(sha1));
87-
pos = -pos-1;
95+
if (obj_hash_size - 1 <= nr_objs * 2)
96+
grow_object_hash();
8897

89-
objs[pos] = obj;
98+
insert_obj_hash(obj, obj_hash, obj_hash_size);
9099
nr_objs++;
91100
}
92101

0 commit comments

Comments
 (0)