summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nico@fluxnic.net>2013-09-10 18:17:12 -0400
committerJunio C Hamano <gitster@pobox.com>2013-09-11 12:25:33 -0700
commit9f36c9b7f77f188db47b80ae1118856249beaa15 (patch)
treefc85141e788ce1e2c989d155f205e29451916624
parente230c568c4b9a991e3175e5f65171a566fd8e39c (diff)
downloadgit-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.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/object.c b/object.c
index d8a4b1ffbe..5f792cbfd3 100644
--- a/object.c
+++ b/object.c
@@ -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;