sha1_name.c: refactor find_short_packed_object()

Extract the logic to find object(s) that match a given prefix inside a single pack into a separate helper function, and give it a bit more comment. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jun 18, 2012 at 13:10 UTC f703e6ea5e3bc7ff39b3ef6d3a21208fb63dfabd
1 file changed +56 -47
sha1_name.c
+56 -47
@@ -78,6 +78,59 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
78 return 1;
79 }
80
81 +static int unique_in_pack(int len,
82 + const unsigned char *match,
83 + struct packed_git *p,
84 + const unsigned char **found_sha1,
85 + int seen_so_far)
86 +{
87 + uint32_t num, last, i, first = 0;
88 + const unsigned char *current = NULL;
89 +
90 + open_pack_index(p);
91 + num = p->num_objects;
92 + last = num;
93 + while (first < last) {
94 + uint32_t mid = (first + last) / 2;
95 + const unsigned char *current;
96 + int cmp;
97 +
98 + current = nth_packed_object_sha1(p, mid);
99 + cmp = hashcmp(match, current);
100 + if (!cmp) {
101 + first = mid;
102 + break;
103 + }
104 + if (cmp > 0) {
105 + first = mid+1;
106 + continue;
107 + }
108 + last = mid;
109 + }
110 +
111 + /*
112 + * At this point, "first" is the location of the lowest object
113 + * with an object name that could match "match". See if we have
114 + * 0, 1 or more objects that actually match(es).
115 + */
116 + for (i = first; i < num; i++) {
117 + current = nth_packed_object_sha1(p, first);
118 + if (!match_sha(len, match, current))
119 + break;
120 +
121 + /* current matches */
122 + if (!seen_so_far) {
123 + *found_sha1 = current;
124 + seen_so_far++;
125 + } else if (seen_so_far) {
126 + /* is it the same as the one previously found elsewhere? */
127 + if (hashcmp(*found_sha1, current))
128 + return 2; /* definitely not unique */
129 + }
130 + }
131 + return seen_so_far;
132 +}
133 +
134 static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)
135 {
136 struct packed_git *p;
@@ -85,53 +138,9 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
138 int found = 0;
139
140 prepare_packed_git();
88 - for (p = packed_git; p && found < 2; p = p->next) {
89 - uint32_t num, last;
90 - uint32_t first = 0;
91 - open_pack_index(p);
92 - num = p->num_objects;
93 - last = num;
94 - while (first < last) {
95 - uint32_t mid = (first + last) / 2;
96 - const unsigned char *current;
97 - int cmp;
98 -
99 - current = nth_packed_object_sha1(p, mid);
100 - cmp = hashcmp(match, current);
101 - if (!cmp) {
102 - first = mid;
103 - break;
104 - }
105 - if (cmp > 0) {
106 - first = mid+1;
107 - continue;
108 - }
109 - last = mid;
110 - }
111 - if (first < num) {
112 - const unsigned char *current, *next;
113 - current = nth_packed_object_sha1(p, first);
114 - if (match_sha(len, match, current)) {
115 - next = nth_packed_object_sha1(p, first+1);
116 - if (!next|| !match_sha(len, match, next)) {
117 - /* unique within this pack */
118 - if (!found) {
119 - found_sha1 = current;
120 - found++;
121 - }
122 - else if (hashcmp(found_sha1, current)) {
123 - found = 2;
124 - break;
125 - }
126 - }
127 - else {
128 - /* not even unique within this pack */
129 - found = 2;
130 - break;
131 - }
132 - }
133 - }
134 - }
141 + for (p = packed_git; p && found < 2; p = p->next)
142 + found = unique_in_pack(len, match, p, &found_sha1, found);
143 +
144 if (found == 1)
145 hashcpy(sha1, found_sha1);
146 return found;