diff options
author | Nicolas Pitre <nico@fluxnic.net> | 2013-09-10 18:17:12 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-09-11 12:25:33 -0700 |
commit | 9f36c9b7f77f188db47b80ae1118856249beaa15 (patch) | |
tree | fc85141e788ce1e2c989d155f205e29451916624 | |
parent | e230c568c4b9a991e3175e5f65171a566fd8e39c (diff) | |
download | git-9f36c9b7f77f188db47b80ae1118856249beaa15.tar.gz |
lookup_object: remove hashtable_index() and optimize hash_obj()np/lookup-object-hashing
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>
-rw-r--r-- | object.c | 22 |
1 files changed, 10 insertions, 12 deletions
@@ -43,16 +43,17 @@ int type_from_string(const char *str) die("invalid object type \"%s\"", str); } -static unsigned int hash_obj(struct object *obj, unsigned int n) +static unsigned int hash_obj(const unsigned char *sha1, unsigned int n) { unsigned int hash; - memcpy(&hash, obj->sha1, sizeof(unsigned int)); - return hash % n; + memcpy(&hash, sha1, sizeof(unsigned int)); + /* Assumes power-of-2 hash sizes in grow_object_hash */ + return hash & (n - 1); } static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size) { - unsigned int j = hash_obj(obj, size); + unsigned int j = hash_obj(obj->sha1, size); while (hash[j]) { j++; @@ -62,13 +63,6 @@ static void insert_obj_hash(struct object *obj, struct object **hash, unsigned i hash[j] = obj; } -static unsigned int hashtable_index(const unsigned char *sha1) -{ - unsigned int i; - memcpy(&i, sha1, sizeof(unsigned int)); - return i % obj_hash_size; -} - struct object *lookup_object(const unsigned char *sha1) { unsigned int i, first; @@ -77,7 +71,7 @@ struct object *lookup_object(const unsigned char *sha1) if (!obj_hash) return NULL; - first = i = hashtable_index(sha1); + first = i = hash_obj(sha1, obj_hash_size); while ((obj = obj_hash[i]) != NULL) { if (!hashcmp(sha1, obj->sha1)) break; @@ -101,6 +95,10 @@ struct object *lookup_object(const unsigned char *sha1) static void grow_object_hash(void) { int i; + /* + * Note that this size must always be power-of-2 to match hash_obj + * above. + */ int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size; struct object **new_hash; |