Commit f6b26e770ffae621408532c5b2c1aae4fa1c9e49

Michael Schubert 2012-07-27T10:53:09

git_oid_cmp: inline memcmp by hand to optimize git.git uses an inlined hashcmp function instead of memcmp, since it performes much better when comparing hashes (most hashes compared diverge within the first byte). Measurements and rationale for the curious reader: http://thread.gmane.org/gmane.comp.version-control.git/172286

diff --git a/include/git2/oid.h b/include/git2/oid.h
index a05b40a..d6b2d1e 100644
--- a/include/git2/oid.h
+++ b/include/git2/oid.h
@@ -136,7 +136,31 @@ GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src);
  * @param b second oid structure.
  * @return <0, 0, >0 if a < b, a == b, a > b.
  */
-GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
+GIT_INLINE(int) git_oid_cmp(const git_oid *a, const git_oid *b)
+{
+	const unsigned char *sha1 = a->id;
+	const unsigned char *sha2 = b->id;
+	int i;
+
+	for (i = 0; i < GIT_OID_RAWSZ; i++, sha1++, sha2++) {
+		if (*sha1 != *sha2)
+			return *sha1 - *sha2;
+	}
+
+	return 0;
+}
+
+/**
+ * Compare two oid structures for equality
+ *
+ * @param a first oid structure.
+ * @param b second oid structure.
+ * @return true if equal, false otherwise
+ */
+GIT_INLINE(int) git_oid_equal(const git_oid *a, const git_oid *b)
+{
+	return !git_oid_cmp(a, b);
+}
 
 /**
  * Compare the first 'len' hexadecimal characters (packets of 4 bits)
diff --git a/src/oid.c b/src/oid.c
index 8775601..556a2cf 100644
--- a/src/oid.c
+++ b/src/oid.c
@@ -161,11 +161,6 @@ void git_oid_cpy(git_oid *out, const git_oid *src)
 	memcpy(out->id, src->id, sizeof(out->id));
 }
 
-int git_oid_cmp(const git_oid *a, const git_oid *b)
-{
-	return memcmp(a->id, b->id, sizeof(a->id));
-}
-
 int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, unsigned int len)
 {
 	const unsigned char *a = oid_a->id;
diff --git a/src/oidmap.h b/src/oidmap.h
index 5a0bab6..1791adb 100644
--- a/src/oidmap.h
+++ b/src/oidmap.h
@@ -28,13 +28,8 @@ GIT_INLINE(khint_t) hash_git_oid(const git_oid *oid)
 	return h;
 }
 
-GIT_INLINE(int) hash_git_oid_equal(const git_oid *a, const git_oid *b)
-{
-	return (memcmp(a->id, b->id, sizeof(a->id)) == 0);
-}
-
 #define GIT__USE_OIDMAP \
-	__KHASH_IMPL(oid, static kh_inline, const git_oid *, void *, 1, hash_git_oid, hash_git_oid_equal)
+	__KHASH_IMPL(oid, static kh_inline, const git_oid *, void *, 1, hash_git_oid, git_oid_equal)
 
 #define git_oidmap_alloc() kh_init(oid)
 #define git_oidmap_free(h) kh_destroy(oid,h), h = NULL