lookup_object: remove hashtable_index() and optimize hash_obj()

hashtable_index() appears to be a close duplicate of hash_obj(). Keep only the later and make it usable for all cases. Also remove the modulus as this is an expensive operation. The size argument is always a power of 2 anyway, so a simple mask operation provides the same result. On a 'git rev-list --all --objects' run this decreased the time spent in lookup_object from 27.5% to 24.1%. [jc: with a few comments on "modulus turned into mask" by Peff] Signed-off-by: Nicolas Pitre <nico@fluxnic.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nicolas Pitre committed Sep 10, 2013 at 18:17 UTC 9f36c9b7f77f188db47b80ae1118856249beaa15
1 file changed +10 -12
object.c
+10 -12
@@ -43,16 +43,17 @@ int type_from_string(const char *str)
43 die("invalid object type \"%s\"", str);
44 }
45
46 -static unsigned int hash_obj(struct object *obj, unsigned int n)
46 +static unsigned int hash_obj(const unsigned char *sha1, unsigned int n)
47 {
48 unsigned int hash;
49 - memcpy(&hash, obj->sha1, sizeof(unsigned int));
50 - return hash % n;
49 + memcpy(&hash, sha1, sizeof(unsigned int));
50 + /* Assumes power-of-2 hash sizes in grow_object_hash */
51 + return hash & (n - 1);
52 }
53
54 static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size)
55 {
55 - unsigned int j = hash_obj(obj, size);
56 + unsigned int j = hash_obj(obj->sha1, size);
57
58 while (hash[j]) {
59 j++;
@@ -62,13 +63,6 @@ static void insert_obj_hash(struct object *obj, struct object **hash, unsigned i
63 hash[j] = obj;
64 }
65
65 -static unsigned int hashtable_index(const unsigned char *sha1)
66 -{
67 - unsigned int i;
68 - memcpy(&i, sha1, sizeof(unsigned int));
69 - return i % obj_hash_size;
70 -}
71 -
66 struct object *lookup_object(const unsigned char *sha1)
67 {
68 unsigned int i, first;
@@ -77,7 +71,7 @@ struct object *lookup_object(const unsigned char *sha1)
71 if (!obj_hash)
72 return NULL;
73
80 - first = i = hashtable_index(sha1);
74 + first = i = hash_obj(sha1, obj_hash_size);
75 while ((obj = obj_hash[i]) != NULL) {
76 if (!hashcmp(sha1, obj->sha1))
77 break;
@@ -101,6 +95,10 @@ struct object *lookup_object(const unsigned char *sha1)
95 static void grow_object_hash(void)
96 {
97 int i;
98 + /*
99 + * Note that this size must always be power-of-2 to match hash_obj
100 + * above.
101 + */
102 int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size;
103 struct object **new_hash;
104