Add git_oid_strcmp and use it for git_oid_streq Add a new git_oid_strcmp that compares a string OID with a hex oid for sort order, and then reimplement git_oid_streq using it. This actually should speed up git_oid_streq because it only reads as far into the string as it needs to, whereas previously it would convert the whole string into an OID and then use git_oid_cmp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
diff --git a/include/git2/oid.h b/include/git2/oid.h
index c35acdc..8d93e79 100644
--- a/include/git2/oid.h
+++ b/include/git2/oid.h
@@ -202,6 +202,16 @@ GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len);
GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str);
/**
+ * Compare an oid to an hex formatted object id.
+ *
+ * @param id oid structure.
+ * @param str input hex string of an object id.
+ * @return -1 if str is not valid, <0 if id sorts before str,
+ * 0 if id matches str, >0 if id sorts after str.
+ */
+GIT_EXTERN(int) git_oid_strcmp(const git_oid *id, const char *str);
+
+/**
* Check is an oid is all zeros.
*
* @return 1 if all zeros, 0 otherwise.
diff --git a/src/oid.c b/src/oid.c
index 4b66990..c7ce6ee 100644
--- a/src/oid.c
+++ b/src/oid.c
@@ -194,14 +194,31 @@ int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, size_t len)
return 0;
}
-int git_oid_streq(const git_oid *a, const char *str)
+int git_oid_strcmp(const git_oid *oid_a, const char *str)
{
- git_oid id;
+ const unsigned char *a = oid_a->id;
+ unsigned char strval;
+ int hexval;
- if (git_oid_fromstr(&id, str) < 0)
- return -1;
+ for (a = oid_a->id; *str && (a - oid_a->id) < GIT_OID_RAWSZ; ++a) {
+ if ((hexval = git__fromhex(*str++)) < 0)
+ return -1;
+ strval = hexval << 4;
+ if (*str) {
+ if ((hexval = git__fromhex(*str++)) < 0)
+ return -1;
+ strval |= hexval;
+ }
+ if (*a != strval)
+ return (*a - strval);
+ }
- return git_oid_cmp(a, &id) == 0 ? 0 : -1;
+ return 0;
+}
+
+int git_oid_streq(const git_oid *oid_a, const char *str)
+{
+ return git_oid_strcmp(oid_a, str) == 0 ? 0 : -1;
}
int git_oid_iszero(const git_oid *oid_a)
diff --git a/tests-clar/core/oid.c b/tests-clar/core/oid.c
index d863a3e..7ee6fb6 100644
--- a/tests-clar/core/oid.c
+++ b/tests-clar/core/oid.c
@@ -16,17 +16,39 @@ void test_core_oid__initialize(void)
void test_core_oid__streq(void)
{
- cl_assert(git_oid_streq(&id, str_oid) == 0);
- cl_assert(git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == -1);
+ cl_assert_equal_i(0, git_oid_streq(&id, str_oid));
+ cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- cl_assert(git_oid_streq(&id, "deadbeef") == -1);
- cl_assert(git_oid_streq(&id, "I'm not an oid.... :)") == -1);
-
- cl_assert(git_oid_streq(&idp, "ae90f12eea699729ed0000000000000000000000") == 0);
- cl_assert(git_oid_streq(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == -1);
+ cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeef"));
+ cl_assert_equal_i(-1, git_oid_streq(&id, "I'm not an oid.... :)"));
- cl_assert(git_oid_streq(&idp, "deadbeef") == -1);
- cl_assert(git_oid_streq(&idp, "I'm not an oid.... :)") == -1);
+ cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed0000000000000000000000"));
+ cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed"));
+ cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ed1"));
+ cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ec"));
+ cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+
+ cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeef"));
+ cl_assert_equal_i(-1, git_oid_streq(&idp, "I'm not an oid.... :)"));
+}
+
+void test_core_oid__strcmp(void)
+{
+ cl_assert_equal_i(0, git_oid_strcmp(&id, str_oid));
+ cl_assert(git_oid_strcmp(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0);
+
+ cl_assert(git_oid_strcmp(&id, "deadbeef") < 0);
+ cl_assert_equal_i(-1, git_oid_strcmp(&id, "I'm not an oid.... :)"));
+
+ cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed0000000000000000000000"));
+ cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed"));
+ cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ed1") < 0);
+ cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ec") > 0);
+ cl_assert(git_oid_strcmp(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0);
+
+ cl_assert(git_oid_strcmp(&idp, "deadbeef") < 0);
+ cl_assert_equal_i(-1, git_oid_strcmp(&idp, "I'm not an oid.... :)"));
+}
void test_core_oid__ncmp(void)
{