object-name: simplify computing common prefixes
The function `extend_abbrev_len()` computes the length of common hex
characters between two object IDs. This is done by:
- Making the caller provide the `hex` string for the needle object ID.
- Comparing every hex position of the haystack object ID with
`get_hex_char_from_oid()`.
Turning the binary representation into hex first is roundabout though:
we can simply compare the binary representation and give some special
attention to the final nibble.
Introduce a new function `oid_common_prefix_hexlen()` that does exactly
this and refactor the code to use the new function. This allows us to
drop the `struct min_abbrev_data::hex` field. Furthermore, this function
will be used in by some other callsites in subsequent commits.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
parent
67f47eab61
commit
1a2842d1b1
18
hash.c
18
hash.c
|
|
@ -317,3 +317,21 @@ const struct git_hash_algo *unsafe_hash_algo(const struct git_hash_algo *algop)
|
||||||
/* Otherwise use the default one. */
|
/* Otherwise use the default one. */
|
||||||
return algop;
|
return algop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned oid_common_prefix_hexlen(const struct object_id *a,
|
||||||
|
const struct object_id *b)
|
||||||
|
{
|
||||||
|
unsigned rawsz = hash_algos[a->algo].rawsz;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < rawsz; i++) {
|
||||||
|
if (a->hash[i] == b->hash[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((a->hash[i] ^ b->hash[i]) & 0xf0)
|
||||||
|
return i * 2;
|
||||||
|
else
|
||||||
|
return i * 2 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawsz * 2;
|
||||||
|
}
|
||||||
|
|
|
||||||
3
hash.h
3
hash.h
|
|
@ -396,6 +396,9 @@ static inline int oideq(const struct object_id *oid1, const struct object_id *oi
|
||||||
return !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);
|
return !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned oid_common_prefix_hexlen(const struct object_id *a,
|
||||||
|
const struct object_id *b);
|
||||||
|
|
||||||
static inline void oidcpy(struct object_id *dst, const struct object_id *src)
|
static inline void oidcpy(struct object_id *dst, const struct object_id *src)
|
||||||
{
|
{
|
||||||
memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
|
memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
|
||||||
|
|
|
||||||
|
|
@ -585,32 +585,16 @@ static unsigned msb(unsigned long val)
|
||||||
struct min_abbrev_data {
|
struct min_abbrev_data {
|
||||||
unsigned int init_len;
|
unsigned int init_len;
|
||||||
unsigned int cur_len;
|
unsigned int cur_len;
|
||||||
char *hex;
|
|
||||||
struct repository *repo;
|
struct repository *repo;
|
||||||
const struct object_id *oid;
|
const struct object_id *oid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline char get_hex_char_from_oid(const struct object_id *oid,
|
|
||||||
unsigned int pos)
|
|
||||||
{
|
|
||||||
static const char hex[] = "0123456789abcdef";
|
|
||||||
|
|
||||||
if ((pos & 1) == 0)
|
|
||||||
return hex[oid->hash[pos >> 1] >> 4];
|
|
||||||
else
|
|
||||||
return hex[oid->hash[pos >> 1] & 0xf];
|
|
||||||
}
|
|
||||||
|
|
||||||
static int extend_abbrev_len(const struct object_id *oid,
|
static int extend_abbrev_len(const struct object_id *oid,
|
||||||
struct min_abbrev_data *mad)
|
struct min_abbrev_data *mad)
|
||||||
{
|
{
|
||||||
unsigned int i = mad->init_len;
|
unsigned len = oid_common_prefix_hexlen(oid, mad->oid);
|
||||||
while (mad->hex[i] && mad->hex[i] == get_hex_char_from_oid(oid, i))
|
if (len != hash_algos[oid->algo].hexsz && len >= mad->cur_len)
|
||||||
i++;
|
mad->cur_len = len + 1;
|
||||||
|
|
||||||
if (mad->hex[i] && i >= mad->cur_len)
|
|
||||||
mad->cur_len = i + 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -785,7 +769,6 @@ int repo_find_unique_abbrev_r(struct repository *r, char *hex,
|
||||||
mad.repo = r;
|
mad.repo = r;
|
||||||
mad.init_len = len;
|
mad.init_len = len;
|
||||||
mad.cur_len = len;
|
mad.cur_len = len;
|
||||||
mad.hex = hex;
|
|
||||||
mad.oid = oid;
|
mad.oid = oid;
|
||||||
|
|
||||||
find_abbrev_len_packed(&mad);
|
find_abbrev_len_packed(&mad);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue