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;