Skip to content

Commit f703e6e

Browse files
committed
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 <[email protected]>
1 parent 1b27c2f commit f703e6e

File tree

1 file changed

+56
-47
lines changed

1 file changed

+56
-47
lines changed

sha1_name.c

Lines changed: 56 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -78,60 +78,69 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
7878
return 1;
7979
}
8080

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+
81134
static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)
82135
{
83136
struct packed_git *p;
84137
const unsigned char *found_sha1 = NULL;
85138
int found = 0;
86139

87140
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+
135144
if (found == 1)
136145
hashcpy(sha1, found_sha1);
137146
return found;

0 commit comments

Comments
 (0)